#!/usr/bin/env perl

use XyceRegression::Tools;
use Scalar::Util qw(looks_like_number);

$Tools = XyceRegression::Tools->new();

# The input arguments to this script are: 
# $1 = location of Xyce binary
# $2 = location of xyce_verify.pl script -- not used
# $3 = location of compare script -- not used
# $4 = location of circuit file to test
# $5 = location of gold standard prn file

$XYCE=$ARGV[0];
$CIRFILE=$ARGV[3];
$GOLDPRN=$ARGV[4];

# define verbosePrint
use Getopt::Long;
&GetOptions( "verbose!" => \$verbose );
if (defined($verbose)) { $Tools->setVerbose(1); }
sub verbosePrint { $Tools->verbosePrint(@_); }

# these are the tolerances used in comparing the .prn file
# and the Gold Standard
my $absTol = 1.0e-8;
my $relTol = 0.001;

# generate .prn file to be tested             
$retval = -1;
$retval=$Tools->wrapXyce($XYCE,$CIRFILE);
if ($retval != 0) { print "Exit code = $retval\n"; exit $retval; }
if (not -s "$CIRFILE.prn" ) { print "Exit code = 14\n"; exit 14; }

# open files and check that the files have the same number of lines
if (not -s "$GOLDPRN" ) { print STDERR "Missing Gold Standard file: $GOLDPRN\nExit code = 2\n"; exit 2; }
if (not -s "$CIRFILE.prn" ) { print STDERR "Missing .prn file: $CIRFILE.prn\nExit code = 14\n"; exit 14; }

open(GSFILE,"$GOLDPRN");
open(PRNFILE,"$CIRFILE.prn");

for ($prnCount=0; <PRNFILE>; $prnCount++) { }
for ($gsCount=0; <GSFILE>; $gsCount++) { }

close(GSFILE);
close(PRNFILE);

$retval=0;
if ($prnCount != $gsCount) 
{
    print STDERR ".prn file doesn't match the Gold Standard\n";
    print STDERR ".prn line count= $prnCount\n";
    print STDERR "Gold Standard line count= $gsCount\n";
    $retval=2;
}
else
{  # If the line counts match, then compare in detail.
   # Re-open the files and compare them line by line.
    open(GSFILE,"$GOLDPRN");
    open(PRNFILE,"$CIRFILE.prn");
    $lineCount=0;
    while( ($lineGS=<GSFILE>) && ($linePRN=<PRNFILE>) )
    {
	 $lineCount++;
         # process a line into text and values.
         chop $lineGS;
         # Remove leading spaces on lineGS, otherwise the spaces become 
         # element 0 of "@gsData" instead of the first column of data.
         $lineGS =~ s/^\s*//;
         @gsData = (split(/[\s,]+/, $lineGS));

         # process a line into text and values.
         chop $linePRN;
         # Remove leading spaces on line, otherwise the spaces become 
         # element 0 of "prnData" instead of the first column of data.
	 $linePRN =~ s/^\s*//;
         @prnData = (split(/[\s,]+/, $linePRN));
             
         if ($#gsData != $#prnData)
         {
             print STDERR ".prn file and Gold Standard have a different # of elements on line $lineCount:\n";
             print STDERR ".prn file had $#prnData elements\n";
             print STDERR "Gold Standard had $#gsData elements\n";
             $retval=2;
         }
         else
         {
             # the two files have the same number of items on a line.  
             # compare individual values as scalars  This will have the 
             # effect of 
             for( $i=0; $i<=$#prnData; $i++ )
             {
                 if ( looks_like_number($prnData[$i]) && looks_like_number($gsData[$i]) )
                 {
                     if( (abs( $prnData[$i] - $gsData[$i] ) < $absTol ) ) 
                     {
                         # two numeric fields match to within specified absolute tolerance
                     }
                     else
                     {
                        print STDERR "Numeric difference in column $i on line $lineCount: \n";
                        print STDERR ".prn file had \"$prnData[$i]\" while Gold Standard had \"$gsData[$i]\" \n";
                        $retval=2;
                        last;
                     }
                 }
                 elsif( ($prnData[$i] eq $gsData[$i]) ) 
                 {
                     # two string fields match
                 }
                 else
                 {
                     print STDERR "String elements failed compare on line $lineCount:\n";
                     print STDERR ".prn file produced: \"$prnData[$i]\" \n";
                     print STDERR "Gold Standard was: \"$gsData[$i]\" \n";
                     $retval=2;
                     last;
                 }                 
             }     
         }
     }

     # close files
     close(GSFILE);
     close(PRNFILE);
}

# print success or failure
if ( $retval != 0 )
{
     verbosePrint "Test Failed!\n";
     print "Exit code = $retval\n"; 
     exit $retval;
}
else            
{
     verbosePrint "Test Passed!\n";
     print "Exit code = $retval\n"; 
     exit $retval;
}
