#!/usr/bin/env perl

$cvs  = 0;
$diff = 0;
$settag = 0;
$deltag = 0;
$setbranch = 0;
$list = 0;
$module = "";
@tARGV = ();
for (; @ARGV > 0; ) {
    if ($ARGV[0] eq "-diff") {
	$diff = 1;
        shift; next;
    }
    if ($ARGV[0] eq "-tag") {
	$settag = 1;
        shift; next;
    }
    if ($ARGV[0] eq "-branch") {
	$setbranch = 1;
        shift; next;
    }
    if ($ARGV[0] eq "-deltag") {
	$deltag = 1;
        shift; next;
    }
    if ($ARGV[0] eq "-list") {
	$list = 1;
        shift; next;
    }
    if ($ARGV[0] eq "-cvs") {
	$cvs = 1;
        shift; next;
    }
    if ($ARGV[0] eq "-module") {
        shift; 
	$module = $ARGV[0];
        shift; next;
    }
    if ($ARGV[0] eq "-h")     { &usage (); }
    if ($ARGV[0] eq "-help")  { &usage (); }
    if ($ARGV[0] eq "--help") { &usage (); }
    @tARGV = (@tARGV, $ARGV[0]);
    shift;
}
@ARGV = @tARGV;

$distdir = "tagsets";

if (!$list && @ARGV != 1) { &usage (); }
if ( $list && @ARGV != 0) { &usage (); }

$file = "$distdir/$ARGV[0].dst";
open (FILE, $file) || die "ERROR: can't open distribution file\n";
@list = <FILE>;
close (FILE);

$version = $ARGV[0];

@name = ();
@tag = ();
@branch = ();

if ($list) { 
    printf STDERR "Available Distributions\n";
    printf STDERR "%-16s  %7s\n", "Module", "Version";
    printf STDERR "-------------------------\n";
}

foreach $line (@list) {
    chop $line;
    if ($line =~ m|^\s*$|) { next; }
    if ($line =~ m|^\s*\#|) { next; }

    ($name, $branch, $branchver, $mode) = split (":", $line);
    
    if ($name eq "") { die "missing module name\n"; }
    
    if ($branch eq "") {
	$branch = "HEAD";
    } 
    if ($branch eq "HEAD") {
	$tag = "HEAD";
    }
    if ($branch eq "NONE") { 
	$tag = "NONE";
    }
    if (($tag ne "HEAD") && ($branchver eq "")) {
	$branchver = "0";
    }
    if (($branch ne "HEAD") && ($branch ne NONE)) {
	$tag = "$branch-$branchver";
    }
    if (($branch ne "HEAD") && ($branch ne "NONE") && ($branchver eq "NONE")) {
	$tag = "$branch";
    }
    # print  "module: $name, tag: $tag, branch: $branch\n"; 

    push @name, $name;
    push @branch, $branch;
    push @tag, $tag;
    push @mode, $mode;
}

if ($list) { exit 0; }

if ($diff) { &difflist (); }

if ($settag) { &settags (); }

mkdir $version;
chdir $version;
for ($i = 0; $i < @name; $i++) {
    if (($module ne "") && ($module ne $name[$i])) { next; }
    if ($mode[$i] eq "SKIP") { next; }
    if ($tag[$i] eq "HEAD") {
	&vsystem ("cvs co $name[$i]");
	if ($status) { die "error running cvs"; }
    } else {
	&vsystem ("cvs co -r $tag[$i] $name[$i]");
	if ($status) { die "error running cvs"; }
    }	
}
chdir "..";
if ($cvs) { exit 0; }

&vsystem ("rm -r `find $version -name CVS`");
if (! -e tarballs) { mkdir "tarballs"; }
&vsystem ("tar cvzf tarballs/$version.tgz  $version");
if ($status) { die "error creating tarball\n"; }
exit 0;

sub vsystem {
    print STDERR "@_\n";
    $status = system ("@_");
    $status;
}

sub usage {
    print STDERR "USAGE: mkdist -list\n";
    print STDERR "     : list valid distributions \n\n";
    print STDERR "USAGE: mkdist (group) (version) [-cvs]\n";
    print STDERR "     : make a distribution tarball\n";
    print STDERR "     : -cvs  : only check out the cvs tree, don't make a tarball\n\n";
    print STDERR "USAGE: mkdist -diff (group) (version)\n";
    print STDERR "     : show the difference between the distribution and current tree\n\n";
    exit 2;
}

sub difflist {

    for ($i = 0; $i < @name; $i++) {
	# the base component cannot be rdiffed
	print STDERR "--- $name[$i] ---\n";
	if ($name[$i] eq "base") { next; }
	if ($tag[$i] eq "") {
	    &vsystem ("cvs -q rdiff -s -r HEAD $name[$i]");
	} else {
	    &vsystem ("cvs -q rdiff -s -r $tag[$i] $name[$i]");
	}	
	print STDERR "\n\n";
    }
    exit 0;
}

sub settags {
    print STDERR "setting tags\n";
    for ($i = 0; $i < @name; $i++) {
	# can the base component be tagged?
	if ($name[$i] eq "base") { 
	    # make this automatic by checking it out and cd'ing there
	    print STDERR "remember to set the base tag by hand\n";
	    next; 
	}
	if ($tag[$i] eq "") { next; }
	if ($tag[$i] eq "HEAD") { next; }
	if ($tag[$i] eq "NONE") { next; }
	if ($mode[$i] eq "EXTERN") { 
	    print STDERR "remember to set tag for $name[$i]\n";
	    next; 
	}
	$flag = "";
	if ($setbranch) { 
	    &vsystem ("cvs -q rtag -b $branch[$i] $name[$i]");
	} else {
	    &vsystem ("cvs -q rtag -r $branch[$i] $tag[$i] $name[$i]");
	}
    }
    exit 0;
}
