#!/usr/bin/perl
# File: $CVSROOT/IDEA-DEV/Tools/Test/verify-events-in-summary
# Info: $CVSROOT/IDEA-DEV/COPYRIGHT
# Date: Tue Dec 13 23:18:02 2005
#  CVS: $Id: verify-events-in-summary,v 1.10 2006/01/21 00:19:30 plaunt Exp $

our $ignore_external_token_id = 1;

#
# command line
#

my $cmd_name = "verify-events-in-summary";

sub show_help
{
    print "\nusage: $cmd_name <events_file> <summary_or_log_file> <report_file> [<format>]\n";
    print "\n<events_file> is the gold standard events file";
    print "\n<summary_or_log_file> is the log in which to look for the events";
    print "\n<report_file> is the output file to which the results are sent";
    print "\n<format> is either 'short' or 'long' (default is short)\n\n";
}

#
# Configuration Parameters
#

our $scenario_dir;
our $log_dir;
our $log_file;
our $events_file;
our $summary_file;
our $verification_report_file;

our @summary_events;
our @verification_events;

our @agent_logs;

our $errors = 0;
our $warnings = 0;

our $format = "short";

sub setup_files
{
    $events_file = shift(@ARGV);
    $summary_file = shift(@ARGV);
    $verification_report_file = shift(@ARGV);
    chomp($log_dir = `pwd`);
    $log_file = $log_dir . '/' . $summary_file;
    $log_file =~ s/\.summary//;

    if (! -e $events_file)
    {
        print "\nEvents file '$events_file' not found!\n";
        show_help();
        exit;
    }
    if (! -e $summary_file)
    {
        print "\Summary file '$summary_file' not found!\n";
        show_help();
        exit;
    }
}

sub setup_format
{
    my $arg = shift(@ARGV);

    if ($arg =~ /sh/ || !$arg)
    {
        $format = "short";
    }
    elsif ($arg =~ /med/)
    {
        $format = "medium";
    }
    elsif ($arg =~ /lon/)
    {
        $format = "long";
    }
    else
    {
        print { "REPORT" } "\nUnknown format: $arg\n\n";
        show_help();
        exit;
    }
}

sub show_setup_info
{
    my $log;
    print { "REPORT" } "Validation report for '$log_file'\n\n";
    print { "REPORT" } `date` . "\n";
    print { "REPORT" } `uname -n -r -s` . "\n";
    print { "REPORT" } "File: $verification_report_file\n\n";
    printf { "REPORT" } "   events_file: %s\n", $events_file;
    printf { "REPORT" } "  summary_file: %s\n", $summary_file;
    printf { "REPORT" } "        format: %s\n", $format;
    print { "REPORT" } "\n";
}

sub show_agent_invocations
{
    my $log;
    foreach $log (@agent_logs)
    {
        print { "REPORT" } "Agent Invocation ($log):\n\n";
        print { "REPORT" } `head -15 $log`;
    }
}

sub agent_n_log
{
    my $num = shift;
    my $agent_log = sprintf "agent%d_log", $num;

    printf { "REPORT" } "agent%d_log: %s\n", $num, ${ $agent_log };

    return $agent_log;
}

#
# Events
#

sub read_events_file
{
    my $file = shift;

    open(EVENTS, $file) or die "$file not found! (read_events_file)";

    print "Events file: " . $file . "\n";

    my $raw_line;
    my @line;

    while ($raw_line = <EVENTS>)
    {
        next if $raw_line =~ /^#/;
        next if $raw_line eq "\n";
        $raw_line =~ s/[0-9]+(\.[0-9]+)? //;
        if ($ignore_external_token_id)
        {   
          $raw_line =~ s/\[[0-9]+\]//; # remove the external token id
        }
        push(@verification_events, $raw_line);
    }

    print { "REPORT" } "Read " . scalar(@verification_events) .
        " verification events from $file.\n";

    return;
}

sub read_summary_file
{
    my $file = shift;

    open(SUMMARY, $file) or die "$file not found! (read_summary_file)";

    print "Summary file: " . $file . "\n";

    my $i = 0;
    my $line;

    while ($line = <SUMMARY>)
    {
        $line =~ s/[0-9]+(\.[0-9]+)? //;    # remove the time stamp
        if ($ignore_external_token_id)
        {        
          $line =~ s/\[[0-9]+\]//; # remove the external token id
        }
        #$summary_events{$line} = ++$i;
        push(@summary_events, $line);
    }
    print { "REPORT" } "Read " . scalar(@summary_events) .
        " execution events from $file.\n\n";

    return;
}

sub setup_report_file
{
    open(REPORT, "> $verification_report_file")
        or die "couldn't open $verification_report_file for output!";
}

sub test_for_events_in_summary
{
    my $i;                      # current event number
    my $j;                      # current summary event
    my $event;                  # current event
    my $event_found;            # boolean: true if event found in log
    my $last_event_position = 0; # position of the last event found in
                                # the summary
    my $total_events = scalar(@verification_events);
    my @all_verification_events = @verification_events;

    print "verifying $total_events events...\n";

    foreach $event (@verification_events)
    {
        ++$i;
        $j=0;
        $event_found = 0;

        for (@summary_events)
        {
            ++$j;

            if($_ eq $event)
            {
                # $j-1 now has the index of the event found in the summary
                # print "found event $i, j == $j, last_event_position == $last_event_position\n";
                splice(@summary_events, $j-1, 1); # remove the event from summary
                $event_found = 1;
                last;
            }
        }

        # if the event is not found
        if ( !$event_found )
        {
            $errors++;
            print { "REPORT" } "ERROR: event $i of $total_events NOT FOUND: $event";
        }
        # if the event is found, but possibly out of order (early?)
        elsif ( $j < $last_event_position )
        {
            $warnings++;
            print { "REPORT" } "WARNING: event $i of $total_events out of order: $event";
        }
        elsif ( $format +~ /long/ )
        {
            print { "REPORT" } "FOUND: event $i of $total_events: $event";
        }
        # if the event is found where it ought to be, be happy
        $last_event_position = $j;
    }
}

#
# do the work
#

setup_files();
setup_report_file();
setup_format();

show_setup_info();
show_agent_invocations();
read_events_file($events_file);
read_summary_file($summary_file);

test_for_events_in_summary();

print "\n";

if ($format =~ /long/)
{
    system("cat", $verification_report_file);
}
else
{
    if ( $errors > 0 )
    {
        my $plural = $errors == 1 ? "" : "s";
        print "$errors error$plural found.\n";
    }
    if ( $warnings > 0 )
    {
        my $plural = $warnings == 1 ? "" : "s";
        print "$warnings warning$plural found.\n";
    }
    print "\nReport generated and written to $verification_report_file\n";
}

print "\n";

exit;

# EOF
