use Getopt::Std;
use vars qw($opt_e $opt_s);
use Cwd;

my $total_fails = 0;
my $buildroot = 'c:/tmp/bld';

@javavars = qw(
  JAVA_TARGET
  JAVA_DIR_BUILD
  JAVATOP
  JAVA_CLASSES
  JAVAC
  JAVAH
  JAVAJAR
  JAVA_DEBUG
  JAVA_REL_SUFFIX
  JAVA_CLASSESDIR
  JAVA_INCDIR
  JAVA_JNIDIR
  JAVA_NMIDIR
  JAVA_TARGETVERSION
  JAVA_TARGETVERSION
  JAVA_BOOTCLASSPATHS
  JAVA_EXTDIRS
  JAVA_SOURCEPATHS
  LOCAL_CLASSPATHS0
  LOCAL_CLASSPATHS1
  REQUIRES
  LOCAL_CLASSPATHS
  JAVA_CLASSPATHS
  LOCAL_JAVACFLAGS
  LOCAL_JAVAHFLAGS
  LOCAL_JAVAJARFLAGS
  _SDE_CLASSDEPENDS
  LOCAL_CLASSDEPENDS
  );

map delete $ENV{$_}, @javavars;

$ENV{_TMTGTOS} = 'nt4';
$ENV{_TMTGTOSCLASS} = 'nt';
$ENV{_TMTGTCPUTYPE} = 'i486';
$ENV{_TMTGTCPUCLASS} = 'x86';
$ENV{_TMTGTREL} = 'debug';
$ENV{_TMTGTBUILDROOT} = $buildroot;
$ENV{_TMROOT} = '../..';
#$ENV{_TMROOT} = 'h:/ccm_wa/moreuse/sde-kazakov/sde/sde_template';
$ENV{_TMSITE} = 'ehvssg';
$ENV{UNAME} = 'cygwin';
$ENV{_TMTGTENDIAN} = 'eb';
$ENV{_TMECHO} = '1';
$ENV{JAVATOP} = 'e:/jdk1.3';
$ENV{_TMNODEPENDENCIES} = '1';
$ENV{VCC} = 'C:/Progra~1/Micros~3/VC98';


%GLOBALENV = (%ENV);

$ReportLogfile  = "java_test_report.log";

sub PrintLog {
  my ($string) = @_;

  print STDOUT $string;
  print REPORTLOGFILE $string;
}

sub runtest {
  my ($expected, $cmdRA, %opts) = @_;
  return if ($opt_s ne '') && ("$expected $opts{-id}" !~ /$opt_s/i);
  PrintLog "\n\n----------------------------------------------------------------------\nRunning: ($expected $opts{-id}) @$cmdRA\n";
  my $cwd;
  %ENV = (%GLOBALENV);
  foreach my $o (keys %opts) {
    PrintLog "  $o => ";
    if (ref $opts{$o} eq 'ARRAY') { PrintLog "@{$opts{$o}}\n"; }
    elsif (ref $opts{$o} eq 'HASH') { PrintLog "%{$opts{$o}}\n"; }
    else { PrintLog "$opts{$o}\n"; }
  }
  my %vars;
  my $compname = $opts{-compname} || "tmComp13";
  my $dir_local = "$compname";
  my $comp_build_dir = "$buildroot/comps/$dir_local";

  $cwd = Cwd::getcwd();
  chdir "../$compname" or die "cannot cd to ../$compname\n";
  if ($opts{-nocleanfirst}) {
    PrintLog "Not cleaning first\n";
  } else {
    my $cmd = "rm -rf $comp_build_dir $buildroot/comps/generated/$compname* $buildroot/comps/generated/*/$compname*";
    PrintLog "Cleaning first: $cmd\n";
    system $cmd;
    if (-d $comp_build_dir) {
      PrintLog "**ERROR: not deleted: $comp_build_dir";
      exit 1;
    }
  }
  PrintLog "----------------------------------------------------------------------\n";
  %vars = @{$opts{-set}};
  foreach my $v (keys %vars) {
    PrintLog "set $v $vars{$v}\n";
    $ENV{$v} = $vars{$v};
  }
  system "printenv" if $opt_e;
  my $status = system @$cmdRA;
  PrintLog "Returns: $status => ";
  my $fail = 0;
  $fail = 1 if $expected eq 'ok' && $status != 0;
  $fail = 1 if $expected eq 'fail' && $status == 0;
  PrintLog ($fail ? "(not expected) TESTERROR\n" : "TESTOK\n");
  $total_fails++ if $fail;
  chdir $cwd;
}

sub usage {
  print @_, "\n" if @_;
  print <<EOF;
test.pl [<options>]
 Options:
  -h		Print help and exit.
  -d		Enable debug info.
  -e		Print environment before every make invocation.
  -s ID		Select tests matchin ID (perl regexp)
EOF
  exit $opt_h ? 0 : 1;
}

if (!getopts("dhes:")) {
  usage();
}

usage("") if $opt_h;

if (!exists $ENV{'_TMREPORTS'}) {
	$ReportLogfile       = "$ENV{'_TMROOT'}/$ReportLogfile";
}
else{
	$ReportLogfile       = "$ENV{'_TMREPORTS'}/$ReportLogfile";
}	
open (REPORTLOGFILE,">".$ReportLogfile);

my $BuildLocation = "$ENV{'_TMROOT'}/comps/tmComp13";
chdir ($BuildLocation) or die "Can't chdir to $BuildLocation\n";

# Some values used in the tests below that make tools fail:
$duffOptions = '-oopsOopsLOCAL_CFLAGS -? -- -/';
# These characters are not allowed in a filename under 
# Windows NT (not sure about other versions):
$duffFileName = '"??<"';
# trick to get make to think variable is defined, although value is actually empty:
$undefinedMakeVarValue = '$X $X'; 

runtest 'ok', ["gmake"],
  '-id' => '2',
  '-compname' => 'tmComp12';

runtest 'ok', ["gmake", "var=_SDE_CLASSDEPENDS", "_sde_print_var", "all"],
  '-id' => '1 echo',
  '-set' => ['_TMECHO', '1'];

# this fails because we haven't got a nodebug version of tmComp12:
runtest 'fail', ["gmake"],
  '-id' => '1 nodebug',
  '-set' => ['JAVA_DEBUG', '-g:none'];

# make nodebug version of tmComp12:
runtest 'ok', ["gmake"],
  '-id' => '2 nodebug',
  '-compname' => 'tmComp12',
  '-nocleanfirst' => 1,
  '-set' => ['_TMTGTREL', 'retail'];

runtest 'ok', ["gmake"],
  '-id' => '1 nodebug',
  '-set' => ['JAVA_DEBUG', '-g:none'];

runtest 'ok', ["gmake"],
  '-id' => '1 nodeps',
  '-set' => ['_TMECHO', '', '_TMNODEPENDENCIES', ''];

runtest 'ok', ["gmake"],
  '-id' => '1 retail',
  '-set' => ['_TMTGTREL', 'retail'];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_REQUIRES:none',
  '-set' => ['JAVA_REQUIRES', $undefinedMakeVarValue];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_REQUIRES',
  '-set' => [qw(JAVA_REQUIRES oopsOopsJAVA_REQUIRES)];

runtest 'fail', ["gmake"],
  '-id' => '1 LOCAL_CLASSDEPENDS',
  '-set' => [qw(LOCAL_CLASSDEPENDS oopsOopsLOCAL_CLASSDEPENDS)];

runtest 'ok', ["gmake"],
  '-id' => '1 LOCAL_CLASSDEPENDS',
  '-set' => [qw(LOCAL_CLASSDEPENDS makefile)];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_DEBUG',
  '-set' => [qw(JAVA_DEBUG oopsOopsJAVA_DEBUG)];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_JNIDIR',
  '-set' => ['JAVA_JNIDIR', $duffFileName];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_NMIDIR',
  '-set' => ['JAVA_NMIDIR', $duffFileName];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_INCDIR',
  '-set' => ['JAVA_INCDIR', $duffFileName];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_CLASSESDIR',
  '-set' => ['JAVA_CLASSESDIR', $duffFileName];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_JARFILE',
  '-set' => ['JAVA_JARFILE', $duffFileName];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_REL_SUFFIX',
  '-set' => ['JAVA_REL_SUFFIX', "/oopsOopsJAVA_REL_SUFFIX/$duffFileName"];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVAC',
  '-set' => [qw(JAVAC oopsOopsJAVAC)];

runtest 'fail', ["gmake"],
  '-id' => '1 LOCAL_JAVACFLAGS',
  '-set' => ['LOCAL_JAVACFLAGS', $duffOptions];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVAH',
  '-set' => [qw(JAVAH oopsOopsJAVAH)];

runtest 'fail', ["gmake"],
  '-id' => '1 LOCAL_JAVAHFLAGS',
  '-set' => ['LOCAL_JAVAHFLAGS', $duffOptions];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVAJAR',
  '-set' => [qw(JAVAJAR oopsOopsJAVAJAR)];

runtest 'fail', ["gmake"],
  '-id' => '1 LOCAL_JAVAJARFLAGS',
  '-set' => ['LOCAL_JAVAJARFLAGS', "-X"];

runtest 'fail', ["gmake"],
  '-id' => '1 LOCAL_CLASSPATHS',
  '-set' => [qw(LOCAL_CLASSPATHS oopsOopsLOCAL_CLASSPATHS)];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_BOOTCLASSPATHS JAVA_EXTDIRS',
  '-set' => [qw(JAVA_BOOTCLASSPATHS oopsOopsJAVA_BOOTCLASSPATHS
                JAVA_EXTDIRS oopsOopsJAVA_EXTDIRS)];

runtest 'ok', ["gmake"],
  '-id' => '1 nonative',
  '-set' => ['JAVA_JNICLASSES', $undefinedMakeVarValue, 
             'JAVA_NMICLASSES', $undefinedMakeVarValue,
             'C_SOURCES', $undefinedMakeVarValue];

runtest 'fail', ["gmake"],
  '-id' => '1 nonative_headers',
  '-set' => ['JAVA_JNICLASSES', $undefinedMakeVarValue, 'JAVA_NMICLASSES', $undefinedMakeVarValue];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_JNICLASSES',
  '-set' => [qw(JAVA_JNICLASSES oopsOopsJAVA_JNICLASSES)];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_NMICLASSES',
  '-set' => [qw(JAVA_NMICLASSES oopsOopsJAVA_NMICLASSES)];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVA_CLASSES',
  '-set' => [qw(JAVA_CLASSES oopsOopsJAVA_CLASSES)];

runtest 'fail', ["gmake"],
  '-id' => '1 JAVATOP',
  '-set' => [qw(JAVATOP oopsOopsJAVATOP)];

runtest 'ok', ["gmake"],
  '-id' => '1 normal',
  '-set' => [];

if ($total_fails == 0) {
  PrintLog "All ok.\n";
  close REPORTLOGFILE;
  exit 0;
} else {
  PrintLog "FATAL: no. failures = $total_fails\n";
  close REPORTLOGFILE;
  exit 1;
}
