#!/usr/bin/perl
use warnings;
use strict;

use autodie;
use File::Find;
use File::Slurp;
use Data::Dump qw(dump);

my $dot;
sub dot {
	$dot .= join("\n",@_) . "\n";
	warn "DOT ",@_,$/;
}

sub print_job {
	my ( $name, $job ) = @_;
	warn "JOB $name ",dump($job),$/;

	return unless exists $job->{task};

	$name = $job->{name};

	foreach my $taskset ( keys %{ $job->{task} } ) {
		dot qq|subgraph cluster_${name}_$taskset {	
			style = filled; color=lightgray; label="$name"
			node [style=filled,color=white];
		|;
		my @t = @{ $job->{task}->{$taskset} };
		my $wait = $t[$#t] eq 'wait' && pop @t;
		foreach my $f ( @t ) {
			dot qq|"$name" -> "$f";|;
			dot qq|"$f" -> "${name}_wait";| if $wait;
		}
		dot "} //subgraph";
	}
}

find(sub {
	my $name = $_;
	return if ! m/\.pm$/;
	open(my $fh, '<', $name);
	my $job;
	while(<$fh>) {
		chomp;
		if (/sub\s+(\w+)\s*:\s*Job/) {
			print_job $name => $job;
			$job = { name => $1 };
		} elsif ( m/\$(\w+)->add_task\(\s*'(\w+)'/ ) {
			push @{ $job->{task}->{$1} }, $2;
		} elsif ( m/\$(\w+)->wait/ ) {
			if ( exists $job->{task}->{$1} ) {
				push @{ $job->{task}->{$1} }, 'wait';
			}
		} elsif ( m/\$self->(do\w*)\(\s*'(\w+)'/ ) {
			push @{ $job->{$1} }, $2;
			dot qq|"$job->{name}" -> "$2" [ label="$1" ];|;
		}
	}
	print_job $name => $job;
}, 'lib');

print $dot;

open(my $d, '|-', 'dot -Tpng -o public/gearman.png');
print $d "digraph {\n$dot\n}\n";
close($d);
