#!/usr/bin/perl -w

#  COMPS script (measure component outputs, run times, and state)
#  Use .pscf file to process all components and create .ccft files
#  that contain their specs
#  graphs the run time and output with single component (-S) option

use samplings;

$Soption = 0;  #do just one component, and show its graphs
$Coption = 1; # assume constant
$Loption = 0; # not yet implemented for state
$Voption = 1;
$Roption = 0; #assume systematic sampling

OPT: for ($i = 0;;$i++) { #over all options
  unless (defined($ARGV[$i])) {last OPT;}
  if ($ARGV[$i] eq "-C") {
    $Coption = 1; $Loption = 0;
  }
  if ($ARGV[$i] eq "-L") {
    $Coption = 0; $Loption = 1;
    die "Linear approximation not implemented";
  }
  if ($ARGV[$i] eq "-V") {
    $Voption = 1;
  }
  if ($ARGV[$i] eq "-R") {
    $Roption = 1;
  }
  if ($ARGV[$i] eq "-S") {
    $Soption = 1;
    die "Error reading .ccf file\n" unless(defined($ARGV[$i+1]) && $ARGV[$i+1] =~ m/.ccf$/);
    @components = ($ARGV[$i+1]);
  }
}

$i = 0;
unless ($Soption) {
  #process system configuration file
  $sys_desc = "system.pscf" ;
  open(SYSTEM, $sys_desc ) || die "could not open ", $sys_desc ;
  $comp_name = <SYSTEM>; #discard polish line

  #store component .ccf names
  @components = ();
  while ($comp_name = <SYSTEM>) { #read to end
    chop($comp_name);
    $components[$i] = $comp_name;
    $i++
  }
  close SYSTEM ;
}

# ident.ccft must be present from SYNF processing
#if ($Coption && !$Soption) { #must also do ident file
#  $components[$i++] = "ident.ccf";
  # should adjust this to match other system subdomains,
  # or even replace it with a canned .ccft file
  # TBD
#}


#debug
#foreach $comp (@components) {print $comp."\n"; }

########################################subroutine#######################
sub warnmess{ #print warning based on V option
  unless ($Voption && defined($_[0])) {return;}
  $mess = "";
  MLOOP: for ($wm=0;;$wm++) {
    unless (defined($_[$wm])) {last MLOOP;}
    $mess = $mess.$_[$wm];
  }
warn $mess, "\n";  #don't print line from which this came...
}
###########################################

#for each component process its file and execute test
CCFL: foreach $comp (@components) {
  open(COMP, $comp) || die "could not open the file ", $comp;
  # get the name of the executable
  chop($comp_name = <COMP>) ;
  @tmp = split(" ", $comp_name);
  if ($tmp[0] eq "theory") { #not a real component, skip
    next CCFL;
  }
  #real component, measure it
  #see if the executable is there
  die "component ", $comp_name, " can't be executed." unless (-x $comp_name);
  $comptheory = $comp."t";
#TBD improve to match SYNF processing, and to ignore stateless components
  $ccftsExist = 1; #assume a good .ccft file exists
    @statvec = stat($comp); #for ccf file
    $ccfileTime = $statvec[9];
    @statvec = stat($comp_name); #for executable file
    $binfileTime = $statvec[9];  
  
    if (-e $comptheory) {
      open (CCFT, $comptheory) or die "something wrong with file ",$comptheory;
      $tmp = <CCFT>; #line format:  executable-name L/C R/S
      @tmp = split(" ",$tmp);
      $ccftsExist = 0 unless ((($tmp[2] eq "R") && $Roption) || (($tmp[2] eq "N") && !$Roption));
      $ccftsExist = 0 unless ((($tmp[1] eq "L") && $Loption) || (($tmp[1] eq "C") && $Coption));
      @statvec = stat($comptheory); #for ccft file
      $ccftsExist = 0 unless ($statvec[9] > $ccfileTime && $statvec[9] > $binfileTime);
      close (CCFT);
    } else {
        $ccftsExist = 0;
    }
  if ($ccftsExist && !$Soption) {
    warnmess $comptheory, " up-to-date...";
    next CCFL;
  }

  warnmess "processing ", $comptheory;
  if ($Roption) {
    $utility = "./compR";
  }
  else {
    $utility = "./comp";
  }
  if ($Soption) { # Display the graph of the component
    system "$utility $comp";
  }
  else {
    system $utility." -I ".$comp;
  }
  } # end foreach over components
