#! /usr/bin/perl
use Modern::Perl;
use File::Find;
use YAML;

my %deps_of;

my $call = sub {
    -f && $File::Find::name ~~ /(?<ns>.*)\.pm$/ or return;
    (my $ns = $+{ns}) =~ s,/,::,g; 
    open my $fh,$_ or die "$! while open $_";
    $deps_of{$ns} = [
	map { m[ \b (?: use | require ) \s+ (C4::[^\$\s;(]+) ]x } <$fh>
    ];
};

find( $call, 'C4' );

my %circular;
while ( my ($module, $deps ) = each %deps_of ) {
    for my $d ( @$deps ) {
	next if $module ~~ $d;
	if ( $module ~~ $deps_of{ $d } ) {
	    $circular{$_} ||=[] for $d,$module;
	    for ( $circular{ $d      } ) { $_ ~~ $module or push @$_, $module }
	    for ( $circular{ $module } ) { $_ ~~ $d or push @$_, $d }
	}
    }
}

for
( [ deps => \%deps_of  ]
, [ circ => \%circular ]
) { my ( $desc, $ref ) = @$_;
    open FH,'>',"graphCirc/$desc.yaml" or die "$!";
    say FH YAML::Dump($ref);
    open FH,'>',"graphCirc/$desc.dot" or die "$!";
    say FH render($ref);
}

sub render_deps {
    my ( $net ) = shift;
    if ( my @deps = @{ $$net{$_} } ) {
	qq(\n"$_" -> { )
	, join( ';', map { qq("$_") } @deps )
	, " }"
    }
    else { () }
}

sub render {
    my $net = shift;
    "digraph {"
    , map (render_deps($net), keys %$net) 
    , "}"
}
