#!/usr/bin/env perl

#
# this script is run on go-oo from ~ooweb/ooo-build 
# to auto-pack the source code on milestone release.
# don't forget to update it there.
#

#use strict;

# Towards a more modular build ...

my $tar_opts='cj';

$0 =~ /(.*)\//;
my $dir = $1;
my $module_list = "$dir/modules2.txt";
open MODULES, "$module_list" or die die "Can't open: $module_list: $!";
my %module_map = map {/(.*)=(.*)$/; ($1, [split /,/, $2])} <MODULES> or die;
# /})];

my $force = 0;

my $src;
my $dest;

sub print_help_and_exit()
{
    print "src-package: <src-directory-name> [<destination-directory>] [--force]\n";
    print "   the src will be un-packed into several archives\n";
    print "   prefixed by the last path element\n";
    print "   --force: ignore missing modules\n";
    exit 0;
}

sub slurp_dir_to_hash($)
{
    my $src = shift;
    my %entries;

    opendir my $dirh, "$src" || die "Can't open $src: $!";
    while (my $entry = readdir ($dirh)) {
	next if ($entry =~ /^\./);
	$entries{$entry} = 1;
    }
    closedir ($dirh);
    return \%entries;
}

sub verify_module_map($$)
{
    my $src = shift;
    my $module_map = shift;
    my $failed = 0;

    my $modules = slurp_dir_to_hash ($src);

    print "Verifying module map ...";
    
    for my $section (keys %{$module_map}) {
#	print "check for $section\n";
	for my $module (@{$module_map->{$section}}) {
#	    print "\tcheck for $module\n";
	    if (!defined $modules->{$module}) {
		print "\n\nError: section '$section' contains non-existent module '$module'\n\n";
		$failed = 1 if (!$force);
	    }
	    delete $modules->{$module};
	}
    }
    my @left_over = keys %{$modules};
    if (@left_over) {
	print "\n\nError: modules not included in any section: '@left_over'\n\n";
	$failed = 1;
    }
    
    die "Failed." if ($failed);
    print " done\n";
}

for my $arg (@ARGV) {
    if ($arg eq "--help" || $arg eq '-h') {
	print_help_and_exit();
    } elsif ($arg eq '--force') {
	$force = 1;
    } elsif (!defined $src) {
	$src = $arg;
    } elsif (!defined $dest) {
	$dest = $arg;
    } else {
	die "Too many arguments '$arg'";
    }
}

if (!defined $src) {
    print_help_and_exit();
}
$dest = '.' if (!defined $dest);

-f "$src/vcl/source/gdi/outdev.cxx" || die "$src doesn't look like an OO.o source tree";

verify_module_map ($src, \%module_map);

print STDERR "packing source in $src to directory $dest\n";

for my $a (keys %module_map) {
    print STDERR "\tpack $a ...";
    my $dest_tar = "$src-$a.tar.bz2";
    my $cmd = "tar $tar_opts --dereference -f $dest/$dest_tar ";
    my $newsrc = "$src-$a";
    symlink ($src, $newsrc ) if (! -l $newsrc);

    for my $b (@{$module_map{$a}}) {
	$cmd .= "$newsrc/$b " if (-e "$newsrc/$b");
    }
    if (-f "$dest/$dest_tar") {
	print "\twarning: $dest/$dest_tar exists, skipping\n";
    } else {
	system ($cmd) && die "Failed to execute '$cmd': $!";
    }

    $cmd = "cd $dest; md5sum $dest_tar > $dest_tar.md5";
    system ($cmd) && die "Failed to generate md5: '$cmd': $!";
    print STDERR " done\n";
}
