#!/usr/bin/env perl
#===============================================================================
#
#         FILE: tag_visualise
#
#        USAGE: ./tag_visualise
#
#  DESCRIPTION: Experimental script to generate a GraphViz image from HPR tags
#
#      OPTIONS: ---
# REQUIREMENTS: ---
#         BUGS: ---
#        NOTES: ---
#       AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com
#      VERSION: 0.0.1
#      CREATED: 2015-06-26 20:19:40
#     REVISION: 2015-06-27 13:27:46
#
#===============================================================================

use 5.010;
use strict;
use warnings;
use utf8;

use Config::General;
use Text::CSV_XS;
use GraphViz2;
use Log::Handler;
use DBI;

use Data::Dumper;

#
# Version number (manually incremented)
#
our $VERSION = '0.0.1';

#
# Script and directory names
#
( my $PROG = $0 ) =~ s|.*/||mx;
( my $DIR  = $0 ) =~ s|/?[^/]*$||mx;
$DIR = '.' unless $DIR;

#-------------------------------------------------------------------------------
# Declarations
#-------------------------------------------------------------------------------
#
# Constants and other declarations
#
my $basedir    = "$ENV{HOME}/HPR/Database";
my $configfile = "$basedir/.hpr_db.cfg";
my $outputfile = "$basedir/$PROG.svg";
my $logfile    = "$basedir/$PROG.log";

my ( $dbh, $sth1, $h1 );
my ( $status, @fields, $label );
my ( %id_tags, %tag_ids, %id_title );

#
# Enable Unicode mode
#
binmode STDOUT, ":encoding(UTF-8)";
binmode STDERR, ":encoding(UTF-8)";

#
# Load database configuration data
#
my $conf = Config::General->new(
    -ConfigFile      => $configfile,
    -InterPolateVars => 1,
    -ExtendedAccess  => 1
);
my %config = $conf->getall();

#-------------------------------------------------------------------------------
# Connect to the database
#-------------------------------------------------------------------------------
my $dbhost = $config{database}->{host} // '127.0.0.1';
my $dbname = $config{database}->{name};
my $dbuser = $config{database}->{user};
my $dbpwd  = $config{database}->{password};
$dbh = DBI->connect( "dbi:mysql:host=$dbhost;database=$dbname",
    $dbuser, $dbpwd, { AutoCommit => 1 } )
    or die $DBI::errstr;

#
# Enable client-side UTF8
#
$dbh->{mysql_enable_utf8} = 1;

$sth1 = $dbh->prepare(
#   q{SELECT id,title,tags FROM eps WHERE tags != '' AND date < now()}
    q{SELECT id,title,tags FROM eps WHERE tags != ''}
);

$sth1->execute;
if ( $dbh->err ) {
    die $dbh->errstr;
}

my $csv = Text::CSV_XS->new;

#-------------------------------------------------------------------------------
#  Collect and process the id numbers and tags
#-------------------------------------------------------------------------------
while ( $h1 = $sth1->fetchrow_hashref ) {
    #
    # Parse the tag list
    #
    $status = $csv->parse( $h1->{tags} );
    @fields = $csv->fields();

    #
    # Trim and lowercase all tags
    #
    @fields = map {
        my $t = $_;
        $t =~ s/(^\s+|\s+$)//g;
        lc($t)
    } @fields;

    #
    # Save the id and its tags
    #
    $id_tags{ $h1->{id} } = [@fields];

    #
    # Save the title
    #
    $id_title{ $h1->{id} } = $h1->{title};

    #
    # Save the ids that use each tag
    #
    foreach my $tag (@fields) {
        if ( defined( $tag_ids{$tag} ) ) {
            push( @{ $tag_ids{$tag} }, $h1->{id} );
        }
        else {
            $tag_ids{$tag} = [ $h1->{id} ];
        }
    }
}

printf "No. of tags: %d\n", scalar( keys(%tag_ids) );
printf "No. of ids:  %d\n", scalar( keys(%id_tags) );

#print Dumper( \%id_tags ), "\n\n";
#print '-' x 80,"\n";
#print Dumper( \%tag_ids ), "\n\n";

#
# Use the logger feature
#
my $logger = Log::Handler->new;

$logger->add(
    file => {
        filename       => $logfile,
        maxlevel       => 'debug',
        message_layout => '%m',
        minlevel       => 'error',
    }
);

#
# Make a graph of the tags
#
my $graph = GraphViz2->new(
    logger => $logger,
    global => { directed => 1 },
    graph  => {
        label   => 'HPR Tags & Episodes',
        rankdir => 'LR',
        splines => 'true',
    },
    #   graph  => { splines => 'curved' },
);

#
# Add each tag as a node, and every episode id and title associated with it.
# Join the tag to the episodes with an 'edge'.
#
foreach my $tag ( sort( keys(%tag_ids) ) ) {
    $graph->add_node( name => $tag, label => $tag, color => 'red' );
    foreach my $id ( @{ $tag_ids{$tag} } ) {
        $label = sprintf("hpr%04d",$id);
        $graph->add_node(
            name  => $id,
            label => "$label\n$id_title{$id}",
            shape => 'box',
            color => 'green'
        );
        $graph->add_edge( from => $tag, to => $id );
    }
}

$graph->run( format => 'svg', output_file => $outputfile );

exit;

# vim: syntax=perl:ts=8:sw=4:et:ai:tw=78:fo=tcrqn21:fdm=marker