#!/opt/SUNWstade/bin/perl -I/opt/SUNWstade/lib
#<copyright>
# ----------------------------------------------------------
# Sun Proprietary/Confidential Code
# Copyright 2001, Sun Microsystems, Inc. All rights reserved.
# ----------------------------------------------------------
#</copyright>

use System;
use Util;
use PDM::ConfigFile;
use Modules;
use Matrix;
use Revision;
use Revision::COMMON;
use Getopt::Std;
use strict;
use Process;

#
# runs locally, started from the GUI.
#
my(%opts);

sub usage {
  print <<EOF;
Usage: ras_revcheck -s [status] -p [print] -P [print errors] 
                    -h <hostname>    # will run revcheck on this host
                    -M <module_list|ALL> 
                    -T <tab delimited format>
                    -e <email> -m <matrix> 
                    -b [background, default is foreground] 
                    -l [display valid modules] 
EOF
}

if (!getopts("TPpblse:m:h:M:", \%opts)) {
    usage();
    exit(1);
}

#close(STDERR); close(SDTOUT); close(STDIN);
my $HOME    = System->home_dir();
my $RASPORT = System->getConfigPort($HOME);

System->set_home($HOME);
System->set_rasport($RASPORT);

my($renv, $devs, $hosts,$notifs) = PDM::ConfigFile->read;
System->set_renv($renv);


my $real_host;
if ($opts{h}) {
   if (!($real_host = findHost($opts{h}) )) {
     print "Error: Host $opts{h} does not exist!\n";
     print "If this is the Master host, do not use the -h option\n";
     print_valid_slaves();
     exit;
   }
   $opts{h} = $real_host;
   print "Using slave host: $opts{h}\n";
}

my $MODULES = Util->decode($opts{M});

if (substr($MODULES,0,1) eq '"') {
   $MODULES = substr($MODULES,1,-1);
}

my $MATRIX  = $opts{m} || Matrix->defaultFile();
my $EMAIL   = $opts{e};
my $PRINTERR = $opts{P};
my $TABS     = $opts{T};
my $ID      = "Revision";
my @REPORTS;

if ($opts{l}) {
   &modules_list();
   exit;
}
if ($opts{s}) {
   my $st = Process->status($opts{h}, $ID);
   print "$st \n";
   exit;
}

my $done = 0;
if ($opts{M}) {
  my $st = Process->status($opts{h}, $ID);
  if ($st =~ /Running/) {
     print "Revision checking already running!\n";
     exit(1);
  }

  if($Process::ERROR =~ /Can't connect/){ #'
    print "ERROR: $Process::ERROR \n";
    exit(1);
  }


  my $opts = "-M \"$MODULES\" " if ($MODULES);
  $opts   .= "-e $EMAIL "   if ($EMAIL);
  $opts   .= "-m $MATRIX "      if ($MATRIX);
  Process->run($opts{h}, "bin/ras_revcheck $opts", \&run, !$opts{b}, 60*60, \&printnew);
  $done = 1;
  $opts{p} = 1 if (!$opts{b});
}

if ($opts{p} || $opts{P}) {
   &printit($opts{h}, $ID, $opts{P});
  $done = 1;
}
if (!$done) {
  usage();
  exit(1);
}

sub printnew {
  my($new) = @_;
  # print $new;
}



sub modules_list {
   my $mods   = Modules->load("Revision");
   print "Modules: \n";
   foreach my $x (@$mods) {
	  next if ($x eq "COMMON");
        print "$x|";
   }
	print Revision::COMMON->modules_list();
   print "\n";

}

sub run {
   my $LOG    = System->get_home() . "/DATA/tmp/${ID}_log";

   my($acronym) = $renv->{GSV_ACRONYM};
   
   Process->start($ID);
   
   my ($env)      = Revision->hbas_present();
   my $matrix     = Matrix->read($MATRIX, $env);
   my $installedp = Revision->readInstalledPatches();
   
   my ($include, $errors);
   unlink $LOG;
   my @input_m = split(/\|/, $MODULES);
   if ( !$matrix )  {
         my $db = Revision->warning();
         push (@REPORTS, @$db);
         open(O, ">>$LOG"); print O "Revision check is  done\n"; close(O);
         $include = "";
   } else { 
     my $mods   = Modules->load("Revision");
     foreach my $x (@$mods) {
          if ($MODULES eq "ALL" || index(lc("|$MODULES|"), lc("|$x|")) >= 0) {
             $include .= " $x|";
             my $mod = "Revision::$x";
             my $db;
	     open(O, ">>$LOG"); print O "module $x started\n"; close(O);

             eval {
               $db = $mod->RUN($matrix, $installedp);
             };
             if (!$db) {
               $db = Revision->warning2($x);
               push(@REPORTS, @$db);
             } elsif ($@) {
               $errors .= "ERROR in $mod: $@ \n";
             } else {
               push(@REPORTS, @$db);
             }
             open(O, ">>$LOG"); print O "module $x done\n"; close(O);
             chop($include);
          }
			 elsif ("$x" eq "COMMON") {
				my $cmods = Revision::COMMON->modules_list();
				my($renv, $rdevs, $hosts, $notifs) = PDM::ConfigFile->read;
				foreach my $cmod (@input_m){
				  if ( index(lc("|$cmods|"), lc("|$cmod|")) >= 0){
					 $include .= " $cmod|";
					 my $mod = new Revision::COMMON($cmod);
					 my $db;
					 eval {
						$db = $mod->TYPE_RUN($matrix, $installedp, $devs);
					 };
					 if (!$db) {
						$db = Revision->warning2($x);
						push(@REPORTS, @$db);
					 } elsif ($@) {
						$errors .= "ERROR in $mod: $@ \n";
					 } else {
						push(@REPORTS, @$db);
					 }
					 open(O, ">>$LOG"); print O "module $x done\n"; close(O);
					 chop($include);
				  }
				}
			 }
     }
     if (!$include) {
        $errors = "Invalid module name: $MODULES ";
     }
   } 
   my $report;
   my $result;

   # Start of Getting Matrix Date
   my ($tem1, $tem2, $revi, $expire, $date);
   my ($tem3, $tem4, $updated);
   my($D) =  System->get_home() . "/System/Matrix";
   my $today = substr(Util->get_today(), 0, 10);
   open(OO2,"$D/$MATRIX");
   my $l;
   my $expire = "";
   my $matrixDate;
   my $updateDate; 
   while ($l = <OO2>) {
        if ($l =~ /XXEXPIRATION\s+(.*)/ ){
           $expire = $1;
        }
        if ($l =~ /Created/ ){
           ($tem1, $tem2, $date) = split (/\s+/, $l);
            if (!$expire || $expire ge $today) {
              $matrixDate = " -- $tem2 $date";
            }
        }

        if ($l =~ /Updated/ ){
           ($tem3, $tem4, $updated) = split (/\s+/, $l);
            if (!$expire || $expire ge $updated) {
              $updateDate = " -- $tem4 $updated";
            }
        }


   }
   close(OO2);
   # End of getting Matrix Date 

   $report->{debug}  = 1;
   $report->{include}= $include;
   $report->{data}   = \@REPORTS;
   $report->{date}   = Util->get_today();
   $report->{errors} = $errors;
   my $displayMatrix = $MATRIX;
   if ($matrixDate) {
      $displayMatrix .= $matrixDate;
   }
   $report->{matrix} = $displayMatrix . " $updateDate";
   
   my $text_report = &textReport($report);

   Process->write($report, $ID);
   
   $EMAIL =~ s/\"//g;
   if ($EMAIL) {
     Util->writef(System->get_home() . "/DATA/revision_email",$EMAIL);
     my $url  = Util->makeUrl($renv->{hostname}, "?GO=GUI::Revision::readLastReport");
   
     my $text = "Revision Checking report,  Use Matrix: $report->{matrix} \n".
                "Run on $renv->{hostname} \n\n$text_report";
     use Mail;
     Mail->mail($EMAIL, "Storage_ADE", "Storage A.D.E. Revision Checking Completed", $text, 10);

   }
   
   Process->done($ID);
}

sub printit {
  my($host, $ID, $error_only) = @_;
  my $R = Process->read($host, $ID);
  print $R->{errors};
  print &textReport($R, $host, $error_only);
}


sub textReport {
   my($report, $host, $error_only) = @_;
   my $result;
   my $FORMAT = "%-15.15s %-50.50s %-10.10s %-12s %-12s %-10s %-12s %-10s\n";
   $FORMAT = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" if ($TABS);
   my ($cnt, %KEY);

   my($renv, $devs) = PDM::ConfigFile->read();
   foreach my $d (@$devs) {
      $KEY{$d->{name}} = $d->{key};
      $KEY{$d->{ipno}} = $d->{key};
   }
   
   foreach my $ele (@{$report->{data}}){
      next if ($error_only && $ele->[2] eq "PASS");
      if (defined($ele)){
        if ($TABS) {
	  my $key = $KEY{$ele->[1]};
	  if (!$key){
	    my @N = split(/\./, $ele->[1]);
	    $key = $KEY{$N[0]};
	  }
          $ele->[1] = "$key\t$ele->[1]";  # insert the key in the tab report.
        }

        next if ($ele->[1] eq "N/A"); # To get rid of non monitored devices
        $result .= sprintf($FORMAT, @$ele);
        $cnt++;
      }
   }
   if (!$cnt) {
      if (!$host) {
        $host = "local host machine"; 
      }
      my @input_m = split(/\|/, $MODULES);
      my @re;
      my $ptr;
      my $info = "No device of this type($MODULES) is  present. Please check system set up";
      foreach my $y (@input_m) {
         @re = ($y, undef,'ERR',undef, undef, undef,undef,$info);
         $ptr = \@re;
         $result .= sprintf($FORMAT, @$ptr);
      }
   }
   my $title = sprintf($FORMAT, "Type", "Name","Status",
                "Curr_Ver","Expect_Ver","Curr_Patch", "Expect_Patch","Comments");
   if (!$TABS) {
     $title   .= sprintf($FORMAT, "================",
                "===========================================",
                "==========", "============", "============",
                "==========", "============", "==================");
   }
   
   return "$title\n$result\n";
}


sub findHost {
  my($host) = @_;
  foreach my $h (@$hosts) {
      if (lc($h->{hostname}) eq lc($host)) {
         return $h->{hostname};
      }
  }
  # Didn't match on full name try first part of name
  foreach my $h (@$hosts) {
      my $ix = index($h->{hostname}, ".");
      if($ix > 0){
        my $short = substr($h->{hostname}, 0, $ix);
        if (lc($short) eq lc($host)) {
         return $h->{hostname};
	}
      }
  }

  return undef;
}

sub print_valid_slaves{
   print "Valid slave hosts are:\n";
   foreach my $h (@$hosts) {
     print "  $h->{hostname}\n";
   }
}
