package Agent::9900;
#<copyright>
# ----------------------------------------------------------
# Sun Proprietary/Confidential Code
# Copyright 2001, Sun Microsystems, Inc. All rights reserved.
# ----------------------------------------------------------
#</copyright>

#  $Name:  $ 
#172.20.104.65

use strict;
use Agent;
use base 'Agent';
use Util;
use System;

sub isSelectable {"Sun 9900"}
sub revision {'$Revision: 1.4 $'}

sub new {
  my($self) = Agent->new();

  bless ($self, 'Agent::9900');
  return $self;
}
use vars qw($ERR );

sub RUN {
  my($agent, $static_list, $pass) = @_;
  my ($timelapse, $dc);

  my($renv) = System->get_renv();
  $DB::single = 1;
  my $processed_list = [];

  foreach my $dev ( $agent->deviceList($static_list) ) {
     next if ($dev->{active} eq "N");
     $dc++;  
     my $sys_report = $agent->INSTRUMENTATION($dev);
     my $wwn = $dev->{key};
     my $connect_errs = $sys_report->{"rc.error"};
     my $problems = PDM->get_last_event();

     my($id) = {
                deviceName=> $wwn,
                active    => $dev->{active},
                class     => "storage.9900",
                name      => $dev->{name},
                display   => $dev->{name},
                category  => Report::CAT_9900,
                ip        => $dev->{ipno},
               };

     $sys_report = {} if (!$sys_report);
     $agent->copyDev($dev, $sys_report);
     my $new_rep;
     $sys_report->{'info.noActionable'} = "Frame Level Event only.";

     if ($connect_errs) {   
       $new_rep = Report->new($id, $sys_report,undef, Report::STATUS_CANNOT_CONNECT );
     } else {
       Discover->updateTopoDevice($dev, {report => $sys_report});
       $sys_report->{'id.name'}     = $dev->{name};
       $sys_report->{"id.mgmtLevel"}= $dev->{mgmtLevel};
       $sys_report->{"id.ip"}       = $dev->{ip};
       $sys_report->{"id.ipno"}     = $dev->{ipno};
       $sys_report->{"id.wwn"}      = $dev->{key};
       $new_rep = Report->new($id, $sys_report);

     }
     require Health::9900;
     Health::9900->all_logic($new_rep); 
     PDM->saveReport($new_rep);

     my ($broke, $abort) = $agent->new_events($problems, $dev, 1);
     push(@$processed_list, $dev);
     last if ($broke && $pass == 1 || $abort);

  }

  return $processed_list;
}

sub getWWN {
  my($agent, $name, $host) = @_;
  my($wwn);
  $ERR = undef;
  my $renv = System->get_renv();
  my $TO = $renv->{'timeout.snmp'};

  if (!$host) {
     return &get_WWN({name => $name});
  } else {
     my $rc = Util::Http->getCommand($host, "Agent::9900::WWN&name=$name&HTTP=1" , $TO);
     if ($rc !~ /OK /) {
        $ERR = "9900: getWWN: cannot identify $name on $host";
        return undef;
     } else {
        my $VAR1;
        my $ix = index($rc, "OK ");
        eval substr($rc,$ix+3);
        return $VAR1;
     }
  }
}


sub get_WWN {
  my($q) = @_;

  my $ip = $q->{name};

  my($DIR)   = System->get_home() . "/snmp/bin";
  my($renv)  = System->get_renv();
  my($TO)    = $renv->{'timeout.snmp'} + 80;
  my $rc = {};

  if (Util->ping($ip, 10)) {
    my $MIBDIR   = System->get_home() . "/snmp/share/snmp/mibs";
    $ENV{LD_LIBRARY_PATH} = System->get_home() . "/bin/lib";
    my $public = $renv->{'snmp.community'} || "public";
    my $OPT    = "-v1 -c$public -r1 -t$TO -M$MIBDIR -mall " . System->snmpopt();
    my $com = "$DIR/snmpwalk $OPT $ip enterprises.116.5.11.4.1.1.5";
    my($err0,$O) = Util->run_command($com, "9900.txt", 2*$TO+5);
  
    my $key;
    my $type = "9900";
  
    foreach my $x (@$O) {
       if($x =~ /RAID400/){
         $type = "9960";
       }elsif($x =~ /RAID401/){
         $type = "9910"
       }elsif($x =~ /RAID450/){
         $type = "9980";
       }
       
       my(@a) = split(/ +\= */, $x);
       $a[1] = substr($a[1],1,-1) if (substr($a[1],0,1) eq "\"");
       if ($a[0] =~ /raidlistMibNickName/) {
           $rc->{name} = $a[1];
       } elsif ($a[0] =~ /raidlistSerialNumber/) {
           $key = $a[1];
       }
    }
    $rc->{ip}   = $ip;
    $rc->{ipno} = Util->name2ip($ip);
    $rc->{type} = 9900;
    $rc->{key}  = "$rc->{type}-$key";
    $rc->{wwn}  = $key;
    $rc->{userLabel} = $type;
  } else {
    $rc->{error} = "Cannot ping $ip";
  }
  if ($q->{HTTP}) {
    require Data::Dumper;
    $Data::Dumper::Indent = 0;
    print "\nOK " . Data::Dumper::Dumper($rc) . "\n";
  } else {
    return $rc;
  }
}


  


sub INSTRUMENTATION {
  my($agent, $device) = @_;
  my(@s, %dev, $in, %info);
  my(%R);
  return Report->readTest($device) if (System->get_testMode());

  my($ip)    = $device->{ip};
  my(@counts, @stats, $stat, $x);
  my($DIR)   = System->get_home() . "/snmp/bin";
  my($renv)  = System->get_renv();
  my($TO)    = $renv->{'timeout.snmp'} + 80;
  my $ping_to  = $renv->{'timeout.ping'} || 10;
  my $public = $renv->{'snmp.community'} || "public";

  if (!Util->ping($device->{ipno}, $ping_to)) {
     $R{'rc.error'} = "Cannot ping $device->{name}/$device->{ipno}";
     $R{'rc.key'}   = $device->{key};
     return \%R;
  }         
  Timelapse->startDev( $device);

  my $MIBDIR   = System->get_home() . "/snmp/share/snmp/mibs";
  $ENV{LD_LIBRARY_PATH} = System->get_home() . "/bin/lib";
  my $OPT      = "-v1 -c$public -r1 -t$TO -M$MIBDIR -mall " . System->snmpopt();

  my($err0,$system) = Util->run_command(
           "$DIR/snmpwalk $OPT $ip system", "9900.txt", 2*$TO+5);

  if ($err0) {
     $R{'rc.key'}   = $device->{key};
     $R{'rc.error'} = $err0;
     return \%R;
  }

  my($err3,$enterprise) = Util->run_command(
            "$DIR/snmpwalk $OPT $ip enterprises.116", "9900.txt", $TO +5);

  foreach my $x (@$system) {
     my(@a) = split(/ +\= */, $x);
     $a[1] = substr($a[1],1,-1) if (substr($a[1],0,1) eq "\"");
     $a[0] = substr($a[0],0,-2) if (substr($a[0], -2) eq ".0");
     $R{"system.$a[0]"} = $a[1];
  }

  my($t, $key) = split(/\-/, $device->{key});

  my %MAP = (SM => "Shared Memory", PS => "Power Supply", CSW => "Internal Bus");

  foreach my $x (@$enterprise) {
     my(@a) = split(/ +\= */, $x);
     $a[1] = substr($a[1],1,-1) if (substr($a[1],0,1) eq "\"");
     next if ($a[0] !~ /\.$key$/ && substr($a[0],-2) ne ".0");

     $a[0] = substr($a[0],0,-2) if (substr($a[0], -2) eq ".0");
     $a[0] =~ s/\.$key$//;

     if ($a[0] =~ /^raidExMib/) {
        if ($a[0] !~ /MibVersionManagement/) {
          $R{"info." . substr($a[0],9)} =  $a[1];
        }

     } elsif ($a[0] =~ /^raidlist/) {
        $R{"raid." . substr($a[0],8)} = $a[1];

     } elsif ($a[0] =~ /^dkcHW/) {
        my $vv = $a[1];
        $vv =~ s/\(\d+\)$//;
        $R{"controller." . substr($a[0],5)} = $vv;
     
     } elsif ($a[0] =~ /^dkuHW/) {
        my $vv = $a[1];
        $vv =~ s/\(\d+\)$//;
        $R{"disk." . substr($a[0],5)} = $vv;
     }
  }

  $agent->addIdentification(\%R);
  $R{'rc.key'} = $R{"id.wwn"};
  Timelapse->stopDev( $device);

  return \%R;
}


sub FRUS {
  my($class, $r, $name) = @_;
  my($v) = $r->{_value};
  my $devtype = $r->category();
  my $model = $v->{"system.sysDescr"};
  my @FRUS;

  my $rev = $v->{"raid.DKCMainVersion"};
  my $type = lc($v->{"id.device_userLabel"});
  my $ser = $v->{"raid.SerialNumber"};

  push(@FRUS, [$name, $type, "Processor",   "Processor",   "HDS", $model, $ser,  $rev,  $v->{"controller.Processor"}]);
  push(@FRUS, [$name, $type, "Environment", "Environment", "HDS", $model, "N/A", "N/A", $v->{"controller.Environment"}]);
  push(@FRUS, [$name, $type, "Battery",     "Battery",     "HDS", $model, "N/A", "N/A", $v->{"controller.Battery"}]);
  push(@FRUS, [$name, $type, "Fan",         "Fan",         "HDS", $model, "N/A", "N/A", $v->{"controller.Fan"}]);
  push(@FRUS, [$name, $type, "Power Supply","Power Supply","HDS", $model, "N/A", "N/A", $v->{"controller.PS"}]);
  push(@FRUS, [$name, $type, "Cache",       "Cache",       "HDS", $model, "N/A", "N/A", $v->{"controller.Cache"}]);

  return \@FRUS;

}



sub REPORT {
  my($class, $host, $r, $arg) = @_;

  my($out);
  my($v) = $r->{_value};

  my $last;
  $out = $class->reportHead("9900", $r);
  my $pow = $v->{"controller.PS"} . " /" . $v->{"disk.PS"};
  $pow =~ s/\(\d\)//g;
  my $fan = $v->{"controller.Fan"} . " /" . $v->{"disk.Fan"};
  $fan =~ s/\(\d\)//g;

  $out .=<<EOF;
<tr><td bgcolor=$Style::LIGHT align=right>Name:</td> <td>&nbsp;$v->{'id.device_name'}</td>
         <td bgcolor=$Style::LIGHT align=right>IP:</td>   <td>&nbsp;$v->{'id.device_ip'}</td>
     <tr><td bgcolor=$Style::LIGHT align=right>Product:</td> <td>&nbsp;$v->{'info.Name'}</td>
         <td bgcolor=$Style::LIGHT align=right>Serial#:</td>   <td>&nbsp;$v->{'id.wwn'}</td>
     <tr><td bgcolor=$Style::LIGHT align=right>Power:</td> <td>&nbsp;$pow</td>
         <td bgcolor=$Style::LIGHT align=right>Fan:</td>   <td>&nbsp;$fan</td>
     </table>
EOF
  my %V;
  my %MAP = (SM => "Shared Memory", PS => "Power Supply", CSW => "Internal Bus");
              
  foreach my $e (keys %$v) {
     my ($u1, $rest) = split(/\./, $e, 2);
     my $val = $v->{$e};
     $val =~ s/\(\d+\)//;
     if ($e =~ /UpTime/) {
        $val =~ /:\s+(\d+)/;
        my $secs = $1;
        my $d = int($secs/3600/24);
        my $h = int($secs - ($d*3600*24))/3600;
        $val = sprintf("%d days %d hours", $d, $h );
     }
     my $name = $MAP{$rest} || $rest;
     $V{$u1} .= "<tr><td width=40% align=right bgcolor=$Style::LIGHT>" . 
                $name . ":</td><td>&nbsp;$val</td>";
  }
  foreach my $e ('raid', 'controller','disk', 'info', 'system') {
     $out .= "<table border=1 cellspacing=0 width=95% bgcolor=white>
       <tr><td colspan=2 bgcolor=$Style::DARK><font color=white>&nbsp;<b>" . uc($e) . "</td>";
     $out .= $V{$e}; 
     $out .= "</table>";
  }  
  $out .= "&nbsp;<p>&nbsp;<p>";
  return $out;


}


1;
