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

use System;
use PPRO;
use Labels;
use Util;
use PDM::ConfigFile;
use Getopt::Std;
use strict;
use Process;

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

sub usage {
  print <<EOF;
Usage: ras_patchlist -s -p -S <session> -b

         -c : Use CD ROM as the patch server source.
	 -s : Display status of current command.
         -p : Print report.
         -S : SessionID (use 'storade')
         -b : run command in background.

EOF
}

if (!getopts("S:cspPb", \%opts)) {
    usage();
    exit(1);
}

#close(STDERR); close(SDTOUT); close(STDIN);
my $HOME     = "/opt/SUNWstade";
my $RASPORT  = System->getConfigPort($HOME);

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

my($renv, $devs, $hosts,$notifs, $Config) = PDM::ConfigFile->read;
System->set_renv($renv);
if ($renv->{solution} eq "N") {
   print "Function not available yet outside of a Sun Solution product!\n";
   exit;
}
require Inventory;

my $PRINTERR = $opts{P};
my $MODE     = $opts{m};
my $SID      = $opts{S};
my $ID      = "Patchlist";
my @REPORTS;


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

my $done = 0;
if ($opts{S}) {
  my $st = Process->status($opts{h}, $ID);
  if ($st =~ /Running/) {
     print "Revision Upgrade already running!\n";
     exit(1);
  }
  Process->run($opts{h}, "bin/ras_patchlist -S $SID", \&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}, $Config);
  $done = 1;
}
if (!$done) {
  usage();
  exit(1);
}

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

sub run {
   my $debug;
   Process->start($ID);
   my $cli = PPRO->cli_path();
        
   if ($opts{c}) {
      $cli   .= " -c patchpro_cdrom.conf ";
   } else {
      $cli   .=  PPRO->add_cdrom();	
   }

   my ($err_cnt, $REPORT, $report);
   my $command = "$cli -l -s $SID -r patchlist";
   $debug .= "Generating patch list:\n";
   my($err, $out) = Util->run_command($command, "test", 60*60); # 1 hour timeout
   my($l);
   open(O, "/var/tmp/pprosvc_$SID/patchlist");
   while ($l = <O>) {
      $REPORT .= $l;
   }
   close(O);
   $report->{debug}  = 1;
   $report->{error_cnt}  = $err_cnt;
   $report->{data}   = {trace => $debug, report => $REPORT, stdout => $out};
   $report->{display_method} = "Service::Upgrade::list";
   $report->{date}   = Util->get_today();
   Process->write($report, $ID);
   sleep(5);
   Process->done($ID);
}

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

  my $devs = $Config->devices();

  my $R = Process->read($host, $ID);
  my $ppro = PPRO->parse($R->{data}{report});
  my $stdout = $R->{data}{stdout};
  my $out = "@$stdout";
  $out =~ s/\.\.+/\.\n/g;
  print "TRACE:\n======\n$out\n";

  if ($PPRO::ERROR) {
     print "Error: PPRO::parse XML Error</b>: $PPRO::ERROR\n";
     return;
  }

  if ($ppro->{ERRORS}) {
     print "Error: ppro->{ERRORS}\n";
     return; 
  }

  my %IP;  # map devices by ipno
  foreach my $d (@$devs) {
     $IP{$d->{ipno}} = $d;
  }

  my $LB = Labels->read("Service::Upgrade");
  print "\nPATCH REPORT:";
  print "\n=============\n";

  foreach my $pp (@{$ppro->devices()}) {
      my $inv_d = $IP{$pp->key()};
      my $ip   = $pp->key();
      my $name = $inv_d->{name};
      my $type = lc($pp->type());
      my $dev  = $Config->deviceByIP($ip);
      my ($label, $k, $sev, $info);
      $sev = 0;
      if ($type eq "sunos") {
        $label = $LB->{sp};
        $k     = "host:" . $renv->{hostname};
      } elsif ($dev) {
        $label = "$dev->{type}: $dev->{name}";
        $k     = "$dev->{type}:$dev->{key}";
      } elsif ($name) {
        $label = "$type:$name";
      } else {
        $label = "$type:UNKNOWN";
      }
      my $P = $pp->patches();
      my $pcnt = $#$P +1;
      my $t2 = $LB->{patches};
      print "\n $label: $pcnt patch(es). \n";
      my $cnt;
      foreach my $patch (@$P) {
         my $pid = $patch->{patchID};
         my $syn = $patch->{synopsis};
         my $err = $pp->error($patch->{error});
         my $frus;
         foreach my $fru (@{$patch->frus()}) {
            $frus .= "$fru->{locator}, ";
         }
         if ($frus) {
            chop($frus); chop($frus);
         }
         my $err2 = "   Message: $err->{message}\n  $err->{remedy} \n" if ($err->{message});

         print "   PatchID: $pid \n";
         my $t1 = $syn;
         $t1 .= " " if ($syn && $err2);
         $t1 .= $err2;
         $t1 .= "      Frus: $frus\n" if ($frus);
         print "$t1 \n";
         $cnt++;
      }
  } 
      

}

