#!/usr/bin/perl
#############################################################################
#  dist_cmp,v 1.6 2003/01/22 04:19:42 garlick Exp
#############################################################################
#  Copyright (C) 2001-2002 The Regents of the University of California.
#  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
#  Written by Jim Garlick <garlick@llnl.gov>.
#  UCRL-CODE-2003-004.
#  
#  This file is part of Genders, a cluster configuration database and
#  rdist preprocessor.
#  For details, see <http://www.llnl.gov/linux/genders/>.
#  
#  Genders is free software; you can redistribute it and/or modify it under
#  the terms of the GNU General Public License as published by the Free
#  Software Foundation; either version 2 of the License, or (at your option)
#  any later version.
#  
#  Genders is distributed in the hope that it will be useful, but WITHOUT ANY
#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
#  details.
#  
#  You should have received a copy of the GNU General Public License along
#  with Genders; if not, write to the Free Software Foundation, Inc.,
#  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
#############################################################################

#
# This script makes rdist output more readable by:
# 1) displaying the output for particular nodes in one piece instead
# of interspersed with output of other nodes
# 2) displaying one copy of output that comes from more than one node 
# (with the list of nodes)
# 3) compressing lists of nodes into node ranges
#
require "/usr/lib/genders/hostlist.pl";	# for Hostlist::compress()

use strict;

##
## Main
##

my ($done, $node, $rest, %output, %xoutput);

# read stdin and consolidate the output for each node
while (<>) {
	$done = 0;

	chomp;
	($node, $rest) = split(": ", $_, 2);

	# remove hostname from the startup line
	$rest =~ s/^updating host .*$/updating host/;
	
	# remove hostname from finish line
	# note if we have finished this node so we can ++ $outcount{$node}
	if ($rest =~ s/^updating of .* finished$/updating finished/) {
		$done = 1;
	}

	# push the line on the list for this node
	push(@{$output{$node}}, $rest);

	# if we are finished with this "session", turn the list for the node
	# into a concatenation of lines and add to list of nodes hashed by
	# output lines
	if ($done) {
		flushnode($node, \%output, \%xoutput);
	}
}

# flush remaining data (shouldn't be any on clean rdist)
foreach $node (keys %output) {
	flushnode($node, \%output, \%xoutput);
}

printit(\%xoutput);


##
## Subroutines
##

# anything in %output for $node is flushed to %xoutput
#	$node (IN)		node name
#	\%output (IN/OUT) 	output hash
#	\%xoutput (IN/OUT)	xoutput hash
sub flushnode
{
	my ($node, $output, $xoutput) = @_;
	my $lines;

	# anything still in %output is flushed to xoutput 
	$lines = join("\n", @{${$output}{$node}});
	push(@{${$xoutput}{$lines}}, $node);
	delete(${$output}{$node});
}

# display the contents of %xoutput
#	\%xoutput (IN)		xoutput hash
sub printit
{
	my ($xoutput) = @_;
	my (@nodes, $lines, $line);

	foreach $lines (keys %{$xoutput}) {
		@nodes = sort {$a cmp $b} @{$xoutput{$lines}};
		@nodes = Hostlist::compress(uniq(@nodes));
		printf("%s:\n", join(",", @nodes));
		foreach $line (split(/\n/, $lines)) {
			print("\t$line\n");
		}
		print("\
---------------------------------------------------------------------------\n");
	}
}

# eliminate duplicate values from list
#	@list (IN)	list, possibly containing dups
#	@ulist (RETURN)	uniq'ed list
sub uniq
{
	my @in = @_;
	my @out = ();
	my $el;

	foreach $el (@in) {
		if (!grep(/^$el$/, @out)) {
			push(@out, $el);
		}
	}
	return @out;
}
