#!/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 Getopt::Std;
use Util::Http;
use Modules;
use strict;
use Process;

use Thresholds;
use vars qw ($HOME %opts $ID );



if (!getopts("h:P:c:spd:b?", \%opts) || $opts{'?'}  || substr($opts{h},0,1) eq "-") {
    usage();
    exit(1);
}

$ID = "FCCheck";
System->set_rasport("7654");
System->set_home(System->home_dir() );
my($renv, $devs, $hosts,$notifs) = PDM::ConfigFile->read;
System->set_renv($renv);
System->set_configDevices($devs);

my $cpid;

my $CATS  = $opts{c};
my $SLEEP = $opts{d} || 2;
my $PASS  = $opts{P};  # optional

if ($opts{s}) {
   print Process->status($opts{h}, $ID);
   exit;
}

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

   my $c1 = "-c $opts{c} ";
   $c1 .= "-P $opts{P} " if ($opts{P});
   #                                           -a -b -c ... <not -h>
   Process->run($opts{h}, "bin/ras_fccheck -d $SLEEP $c1", \&run, !$opts{b});
   $done = 1;
   $opts{p} = 1 if (!$opts{b});
}
if ($opts{p}) {
   &printit($opts{h}, $ID);
   $done = 1;
}
if (!$done) {
   usage();
   exit(1);
} 
my $return_value= &get_returnval($opts{h}, $ID);
exit $return_value;
###########################################################################


sub run {
  my $return_value =0;
  my($out);
  my $renv = System->get_renv();
  my($cat) = $renv->{categories}; # verify if agent is active (todo)
  my $found_device = 0;

  Process->start($ID); # pid and erase report file.

  my $agents  = Modules->load("Agent");
  my(@PASS,@INFO,$pno, @o1,$errors);
  my($url, @a, $pass1, $pass2, $VAR1, $data1, $data2, $diff, $i, $x, $counterType, $h, $mach);

  $pass1 = {};
  $pass2 = {};

  if ($PASS == 1) {
     $found_device = &get_report($pass1, $agents, $CATS);
     if($found_device){
        Util->serialize("tmp/fccheck_pass1", $pass1);
        exit;
     }else{
	&get_report($pass2, $agents, $CATS);
     }

  } elsif ($PASS == 2) {
     $pass1 = Util->deserialize("tmp/fccheck_pass1");
     &get_report($pass2, $agents, $CATS);

  } else {
     $found_device = &get_report($pass1, $agents, $CATS);
     if($found_device){
        print "Initial FC counters retrieved\n";
        sleep($SLEEP * 60);
     }else{
        print "Found no devices to check\n";
     }

     &get_report($pass2, $agents, $CATS);
     print "Last FC Counters retrieved\n";
  }
  my $WAIT = $SLEEP;

  Thresholds->init();

# th1 =  [ 100, '1m', '0m', 'E', 'Too many InvalidTxWords' , 'comments'];
 

  $out->{header} = ["#", "Type","Name", "WWN","Component","FCC","+Inc.","Threshold","Desc.", "Details"];
  my @LINES;
  my @ERROR;

  my($th1);
  my(%T) = ();
  $out->{info}{log} = "PASS1:\n" . $pass1->{_log} . "\nPASS2:\n" . $pass2->{_log};
  foreach my $k (keys %$pass1) {
     next if (substr($k,0,1) eq "_"); # info fields
     $data1 = $pass1->{$k}{data};
     $data2 = $pass2->{$k}{data};
    

     if($pass1->{$k}{data_info}){
        
        $out->{info}{log} .= "Counter fields: $pass1->{$k}{data_info}\n";
	$out->{info}{log} .= "___________________________________________\n";
	print "Counter fields: $pass1->{$k}{data_info}\n";
	print                "___________________________________________\n";

     }
     $diff = 0;
     foreach $i (keys %$data1) {
        if (!$data2->{$i}){
	   # This field has gone away??
	   $errors++;
	   print "Location $i has gone away\n";
	   push(@ERROR, "Unable to retrieve information for location $i. Could indicate a potential problem.\n");
	   next;
	}
	my(@c1) = split(/\t/, $data1->{$i});  # old counters
        my(@c2) = split(/\t/, $data2->{$i});
	print "Location $i:\n";
	$out->{info}{log} .= "Location $i:\n";
	print "Original value: @c1\n";
	$out->{info}{log} .= "Original value: @c1\n";
	print "End value:      @c2\n";
	$out->{info}{log} .= "End value:      @c2\n";


        if ($data1->{$i} ne $data2->{$i}) {
           $diff = 1;
           my($hba,$wwn,$comp, $type) = split(/\|/, $i);
           for ($x=0; $x <= $#c2; $x++) {
               if ($c2[$x] > $c1[$x]) {
                  $diff = $c2[$x] - $c1[$x];
                  $counterType = $FC::Counters[$x];
                  if (($th1 = Thresholds->exist("health-$type", $counterType))) {
                      my($x) = $diff * $th1->[1] / $WAIT;
                      if ($x >= $th1->[0]) {
                         $return_value =1;
                         my($min) = $th1->[1];
                         $min =~ s/m/mins/;
                         my($agent) = substr($k,7);
                         my($name) = $pass1->{$k}{enc}{$wwn};
                         $errors++;
                         push(@LINES, [$errors,$agent,$name,$wwn,$comp,
                            $counterType,$diff,"$th1->[0] in $min",$th1->[4],$th1->[5] ]);
                      }
                  }
               }
           }
        }
     }
  }
  $out->{info}{created} = Util->get_today();
  $out->{data} = \@LINES;
  $out->{error} = \@ERROR;
  $out->{pass} = $return_value;
  Process->write($out,  $ID); # write report file.
  Process->done($ID);               # change pid file .
  return; 
}

sub get_report {
  my($report, $agents, $CATS) = @_;

  my($found_devices);
  $found_devices = 0;

  $report->{_categories} = $CATS;
  foreach my $agent0 (sort @$agents) {
    my $agent = "Agent::".$agent0;
    if ($CATS eq "ALL" || index(lc($CATS), lc($agent0)) >= 0) {
      my @dev_list = $agent->deviceList();
      if ($agent->can("FCCounters")) {
        if ($#dev_list < 0) {
           print "  --> No device found for $agent0: skipping.\n";
           next;
        }
        print "  --> Running $agent->FCCounters\n";
        $report->{_log} .= "  --> Running $agent->FCCounters\n";
        $report->{_time} = time;
        $report->{$agent}  = $agent->FCCounters({cache => 0});
        if (!exists($report->{$agent}{data}) ) {
          print "  -->  No fc-counter data for $agent!\n";
          $report->{_log} .= "  -->  No fc-counter data for $agent!\n";
        } else {
          my $d = $report->{$agent}{data};
          my @d1 = (keys %$d);
          if ($#d1 < 0) {
             print "  -->  No fc-counter data for $agent!\n";
             $report->{_log} .= "  -->  No fc-counter data for $agent!\n";
          }else{
	     $found_devices = 1;
	  }
        }
      }
    }
  }
  return $found_devices;
}

sub printit {
   my($host, $ID) = @_;

   my $R = Process->read($host, $ID);
   print "Fibre Channel Check \n";
   #print "#  Type Name  WWN   Component   FCC   +Inc.   Threshold   Desc \n";
   my $FORMAT = "%-2.2s %-8.8s %-20.20s %-17.17s %-10.10s %-5.5s %-7.7s %-15.15s\n";
   my $head = $R->{header};
   printf $FORMAT, @$head;
   my $l1 = "=================================";
   printf $FORMAT, ($l1,$l1,$l1,$l1,$l1,$l1,$l1,$l1);

   my $errors  = $R->{error};
   foreach my $err (@$errors) {
      print  $err;
   }

   my $rows = $R->{data};
   foreach my $r (@$rows) {
      printf $FORMAT, @$r;
   }
   print "No error found!\n" if (($#$rows < 0) && ($#$errors < 0));
   print "Done.\n";
}

sub get_returnval{
   my($host, $ID) = @_;
   my $R = Process->read($host, $ID);
   return $R->{pass};
}

sub usage {
  print <<EOF;
 Usage  : ras_fccheck -h <hostname> 
                  -c "A5K|T3|ALL.." 
                  -s [status] -p [print] 
                  -d [sleep mins] 
                  -P [1|2]        # select pass
                  -b [background, default is foreground] 
                  -?              # usage 
 Example: ras_fccheck -c ALL -P 1
          ras_fccheck -c ALL -P 2 -d 20
EOF
}
