#!/usr/bin/perl -w

use strict;
use Data::Dumper;

my %inc;
my @Inc = (".");
my %ignore = ( # ignore know system files
    "lilypond-book-preamble.ly" => 1,
);

#################### Functions

sub Usage() {
  print STDERR "Usage:
	depend_ly [-I<dir>[:<dir>]...] ly-file(s)
Where
	<dir> is where to find included ly-files
";
  exit 0;
}

sub file_exist($) {
  my $file = shift;
  my $inc;

  foreach (@Inc) {
    if ($_ eq ".") {
      $inc = $file;
    } else {
      $inc = "$_/$file";
    }
    if (stat $inc ) {
      return $inc;
    }
  }
  return undef;
}

# find (recursively) included files
my @scm_load_path = ();
sub ly_inc($) {
  my $file = shift;
#  print "ly_inc: $file\n";

  my $fh;
  my %lst = (); # which files to recursively check

  # no file no dependancies
  open($fh, "<", $file) || return;
  while(<$fh>) {
    s/%.*$//; # get rid of comments

    # find load'ed scheme files
    if (m/^#\(([-a-zA-Z]+)\s+\"([^\"]+)\"\)/) {
	my $form = $1;
	my $arg  = $2;
	#print "form = <$form> / arg = <$arg>\n";
	if ($form eq "add-to-load-path") {
	    unshift @scm_load_path, $arg;
	} elsif ($form eq "load") {
	    #print "path: <", join("> <", @scm_load_path), ">\n";
	    my $file = "";
	    if ($arg =~ m|^/|) {
		if (-r $arg) {
		    $file = $arg;
		}
	    } else {
		for my $p (@scm_load_path) {
		    my $test = "$p/$arg";
		    if (-r $test) {
			$file = $test;
			last;
		    }
		}
	    }
	    #print "file <$file>\n" if ($file);
	    $inc{$file} = 1;
	}
	next;
    }

    # this breaks for multiple \include per line
    m/\\include[ \t]+"([^\"]+)"/ || next;
    my $inc_file = $1;
    if ($ignore{$inc_file}) { next; }
    #print "inc_file: $inc_file\n";

    # consider only existing files as dependancies
    #$inc_file = file_exist $inc_file || next;

    # only add this file to %lst if we have not checked it for dependancies
    if (!$inc{$inc_file}) { $lst{$inc_file} = 1; }

    # add this as an dependancy
    $inc{$inc_file} = 1;
  }
  close($fh);

  foreach (keys(%lst)) {
    &ly_inc($_);
  }
}

#################### Main

if (@ARGV < 1) { Usage(); }

while ($ARGV[0] =~ m/^-I(.*)$/) {
  push @Inc, split(/:/, $1);
  shift @ARGV;
}

my $all = '';
my $file;
my $sep = "";
#my @hdr = hdr();
foreach $file (@ARGV) {
  # reset found dependancies for each new file to check
  %inc = ();
  &ly_inc($file);
  my $stem = $file;
  $stem =~ s/\.ly$//;
  my @lst = sort(keys(%inc));
  unshift @lst, $file;

  print $sep; $sep = "\n";
  print "$stem.ps:\t"   , join(" ", @lst), "\n";

  $all .= " $stem.ps"
}

if ($all) {
  print "\nall:\t$all\n";
}
