#!/usr/bin/perl -w

use Graph::Directed;

my $setupini = shift @ARGV or die("Usage: $0 path-to/setup.ini");

open(IN, "<", $setupini) or die("can't open $setupini for reading: $!");
my @pkgs;

# slurp whole file
{ local $/; @pkgs = split('\n@ ', <IN>); }

my $req = Graph::Directed->new();

foreach (@pkgs) {
  next unless(/^(\S+)/);
  my $pkgname = $1;
  next if $pkgname eq "#";
  
  my $requires = m/^Requires: (.+)$/im && $1 || "";
   
  # print "$pkgname requires [ " . join(", ", split(' +', $requires)) . " ]\n";
  # if(rand(1.0) < 0.250) {
    $req->add_edge($pkgname, $_) foreach split(' +', $requires);
  # }
}

my $tcm = Graph::TransitiveClosure::Matrix->new($req, path_length => 1, path_vertices => 1);
my $pathsoflen;

for my $u ($tcm->vertices) {
  for my $v ($tcm->vertices) {
    next if ($u eq $v) || (!$tcm->is_reachable($u, $v)) || ($tcm->path_length($u, $v) < 2);
    
    push @{$pathsoflen->[$tcm->path_length($u, $v)]}, [ $tcm->path_vertices($u, $v) ];
    
    # print "($u, $v) = ", $tcm->path_length($u, $v), "\n";
  }
}

for (my $i = @$pathsoflen; $i > 2; $i--) {
  print "Chains of length $i:\n";
  foreach my $p (@{$pathsoflen->[$i - 1]}) {
    print "[ " . join(' -> ', @$p) . " ]\n";
  }
}

