#!/usr/bin/perl
#
# This script processes the JAF .cfg file.  In that file, you specify
# your agent's runtime properties, along with commands which write
# out the .gnt file, and generate the .jar file.  It is not essential
# to use this script (the .gnt and .jar files can be easily generated
# by hand), but it will save you time if you use this script to generate
# the .gnt or .jar files for several agents at once.  This is done
# by just including multiple WRITE and JAR commands in the .cfg file.
# You may also include text from other cfg files during the parse
# using the INCLUDE command.
#
# Bryan Horling - April 2001
# ########################################################################

use POSIX;

# Args
my $NUM = 0;
while ($_ = shift @ARGV) {
	if (/^\-/) {
		if (/\-e/) {
			$PRINTENV = 1
		} else {
			usage();
		}
	} else {
		undef $ARGS;
		undef $DEST;
		doconfig($_);
		$NUM++;
	}
}
usage() if (!$NUM);

sub doconfig {
	my($CONFIG) = shift;
	my $FH = $CONFIG;

	# Read it in
	open($FH, $CONFIG) ||
		die "Problem opening $CONFIG ($!).\n";
	while(<$FH>) {
		chop();
		next if (/^\s*;/);
		next if (/^\s*$/);

		# Parse it
		my ($ITEM,$VALUE) = split(/:/,$_,2);
		$ITEM =~ s/^\s*//;
		$ITEM =~ s/\s*$//;
		$VALUE =~ s/^\s*//;
		$VALUE =~ s/\s*$//;

		# Grab the multi-lines (ending in '\')
		while ($VALUE =~ /\\\s*$/) {
			$_ = <$FH>;
			chop();
			next if (/^\s*;/);
			$VALUE =~ s/\\$//;
			s/^\s*//;
			s/\s*$//;
			$VALUE .= $_;
		}

		# Grab the lines
		if ($ITEM =~ /^write$/i) {
			&makegnt($VALUE);
		} elsif ($ITEM =~ /^archive$/i) {
			print ("The ARCHIVE property is deprecated\n");
		} elsif ($ITEM =~ /^include$/i) {
			doconfig($VALUE);
		} elsif ($ITEM =~ /^destination$/i) {
			$DEST = $VALUE . "/";
		} elsif ($ITEM =~ /^code$/i) {
			print ("The CODE property is deprecated\n");
		} elsif ($ITEM =~ /^jar$/i) {
			($JAR,$CONT) = split(/\s+/,$VALUE,2);
			makejar("$DEST/$JAR", $CONT);
		} else {
			if ($VALUE ne "_nil_") {
				$ARGS{$ITEM} = $VALUE;
			} else {
				delete $ARGS{$ITEM};
			}
		}
	}
	close($FH);
}

sub makejar {
	($NAME, $FILES) = @_;

	if ($NAME !~ /\.jar$/) {
		warn "Warning JAR target $NAME does not end in .jar\n";
	}

	my $CONTENTS = "";
	if (-r $NAME) {
		$CONTENTS = `jar tvf $NAME` || "";
	}

	@DEPS = split(/\s+/, $FILES);
	while ($_ = pop(@DEPS)) {
		if (( -C  $NAME >= -C $_) || (! -e $NAME) || ($CONTENTS !~ /$_/)) {
			print "Jar'ing $NAME $FILES\n";
			`jar cvf $NAME $FILES`;
			return;
		}
	}

	print "Jar file \"$NAME\" contents have not changed, update avoided\n";
}

sub makegnt {
	my($NAME) = @_;
	my $KEY;

	if ($DEST eq "") {
		warn "Warning no DESTINATION defined before WRITE $NAME\n";
	}
	if ($NAME !~ /\.gnt$/) {
		warn "Warning WRITE target $NAME does not end in .gnt\n";
	}

	my($FILE) = "$DEST$NAME";
	print "Writing $FILE\n";

	open(GNT, ">$FILE") ||
		die "Problem opening $FILE ($!).\n";
	print GNT "; Config file generated from $CONFIG  (" . strftime("%D %T",localtime()) . ")\n";
	print GNT ";   This is typically generated by a script, but you can also create or\n";
	print GNT ";   edit it by hand.  Each line should contain a single NAME:DATA pair.\n";
	print GNT "; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n";
	print GNT "\n";

	# Get the env args if we should
	if ($PRINTENV) {
		print GNT "; Gathered from environment variables\n";
		foreach $KEY (keys %ENV) {
			if ($KEY =~ /^AGENT_/i) {
				$TEMP = $KEY;
				$TEMP =~ s/^AGENT_//i;
				print GNT "$TEMP:$ENV{$KEY}\n";
			}
		}
		print GNT "\n";
		print GNT "; Gathered from the config file\n";
	}

	foreach $KEY (keys %ARGS) {
		print GNT "$KEY:$ARGS{$KEY}\n";
	}
	close(GNT);
}

sub usage {
	print "Usage: makeconfig <filename>\n";
	print "Commands:\n";
	print "  INCLUDE: Include text from another config file\n";
	print "  WRITE: Write out the config file at given point\n";
	print "  JAR: Create a jar file at given point\n";
	print "Keywords:\n";
	print "  DESTINATION: Destination for .gnt file\n";
	print "Other:\n";
	print "  _nil_: If RHS of line, deletes the key\n";
	exit;
}
