#!/usr/bin/perl

use strict;
use warnings;

# the hash with all sub names
my %sublist;
# the hash containing a hasref of subs in each package ( $packagedetail->{$package}->{$sub} )
my $packagedetail;

# read all C4/* packages
my $dir;
opendir($dir,"C4");
my @packages = readdir($dir);
#   for each, parse the sub and 
foreach my $package (@packages) {
    open FILE, "<:utf8","C4/$package";
    my @lines = <FILE>;
    foreach my $line (@lines) {
        if ($line =~ /^sub (\w*)/) {
            my $subname = $1;
            next if $subname eq "new";
            next if $subname eq "AUTOLOAD";
            next if $subname eq "DESTROY";
            if ($sublist{$subname}) {
                print "duplicate sub : $subname in $package and ".$sublist{$subname}."\n";
            } else {
                $sublist{$subname} = $package;
                $packagedetail->{$package}->{$subname}=1;
            }
        }
    }
}
#use Data::Dumper;
#warn "PACKAGEDETAIL : ".Data::Dumper::Dumper($packagedetail);
#die;
print "======\n";
# OK, now read all packages again, check which package are use-d, and check which sub is used from this package
my $dirToCheck = "C4";
opendir($dir,$dirToCheck);
@packages = readdir($dir);
#   for each, parse the sub see what is loaded, and check which function is run from this loaded package
foreach my $AnalysedPackage (@packages) {
    print "===== checking $AnalysedPackage =====\n";
    open FILE, "<:utf8","$dirToCheck/$AnalysedPackage";
    my @lines = <FILE>;
    foreach my $line (@lines) {
        my $loadedPackage;
        if ($line =~/use C4::(\w*)/) {
            $loadedPackage = $1;
            print "    $AnalysedPackage uses $loadedPackage.pm\n";
        }
        if ($line =~/require C4::(\w*)/) {
            $loadedPackage = $1;
            print "    $AnalysedPackage require $loadedPackage.pm\n";
        }
        # OK, now check that at least one sub from the loaded package is used in the checked package
        if ($loadedPackage) {
            next if $loadedPackage.".pm" eq $AnalysedPackage; # skip package itself
            next if $loadedPackage eq "Context"; # we skip Context, it always used & usefull, no need to check everything
            my $totaluse=0;
            #use Data::Dumper;
            #warn "==> $loadedPackage = ".Data::Dumper::Dumper($packagedetail->{$loadedPackage.".pm"});
            foreach my $checked (keys %{$packagedetail->{$loadedPackage.".pm"}}) {
                #open the package again, and try to find how many time the checked sub is used
                my $total = `grep "$checked(" $dirToCheck/$AnalysedPackage|wc -l`;
                chop $total;
                $totaluse=$totaluse+$total;
                print "        In $AnalysedPackage the $loadedPackage.pm, sub $checked is used $total times\n" if $total;
            }
            # finished analysing the package, if no use, report it
            unless ($totaluse) {
                print "    >>>> There is a use $loadedPackage.pm that is useless in $AnalysedPackage\n";
            }
        }
    }
}
