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

#  $Name: bld61_002 $ 
#  $Id: TAPE.pm,v 1.3 2004/09/15 21:23:58 mckenney Exp $

use strict;
use Agent;
use base 'Agent';
use Luxadm;

sub isSelectable {"FC-Tape"}
sub revision {'$Revision: 1.3 $'}
use vars qw ($ERR );


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

  bless ($self, 'Agent::TAPE');
  return $self;
}

sub RUN {
  my($agent, $static_list, $pass) = @_;
  my($HBA, $logfile, $r, @results);
  my($xml, @lux_dif, $dif, $ev, $found);
  my($log_err, $lines, $timelapse);
  my(%DONE, $report, $device, $wwn, $id, $x, $l, $connect_errs);
  $DB::single=1;
  
  my($pdm) = $agent->get_pdm();
  my($renv) = System->get_renv();
  my $processed_list = [];
  my($today) = Util->today("YMDH");

  my($lux) = System->find_luxadm;

  my($dc) = 0;

  foreach $device ( $agent->deviceList($static_list)) {
    next if ($device->{active} eq "N"); 

    $dc++;
    Debug->print1("-> TapeAgent: Reading device $device->{name}/$device->{wwn}");

    ($wwn, $connect_errs, $report) = $agent->luxadm($device, $lux);
     $wwn = lc($wwn);

     $id = {  
              deviceName  => $device->{key},
              active      => $device->{active},
              logFile     => "",
              display     => "$device->{name} (wwn=$device->{key})",
              name        => $device->{name},
              class       => $device->{class},
              category    => Report::CAT_TAPE, 
              ip          => "",
           };
     $report = {} if (!$report);
     $agent->copyDev($device, $report);

     $HBA = $device->{hba} || System->get_hba;
     $report->{"id.name"} = $device->{name};
     $report->{'id.wwn'} = $device->{wwn};
     my $new_rep;
    
     if ($connect_errs || !$wwn) {
       my $package_samfsr = System->getPackageInfo("", "SUNWsamfsr", "VERSION");
       my $package_samfs = System->getPackageInfo("", "SUNWsamfs", "VERSION");

       if ($connect_errs =~ /Error: SCSI failure/) {
         Debug->print3("Luxadm SCSI failure is not conclusive.");
	 next;  # connect_errs non-conclusive when any tape app is installed bug 4986727, 5016779 and 5048519, 5067391
       } else {
         $report->{'id.connect_errs'} = $connect_errs;
         $new_rep = Report->new($id, $report , undef, Report::STATUS_CANNOT_CONNECT);
       }
     } else {
        $new_rep = Report->new($id, $report , undef);
     }
     require Health::TAPE;
     my $problems = PDM->get_last_event();
     Health::TAPE->all_logic($new_rep);
     PDM->saveReport($new_rep);

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

  return $processed_list;
}


sub getWWN {
  my($agent, $name, $host) = @_;
  my($wwn);
  $ERR = undef;

  if (!$host) {
     return &getWWN({name => $name});
  } else {
     my $rc = Util::Http->getCommand($host, "Agent::TAPE&name=$name&HTTP=1", 20);
     if ($rc =~ /ERR/) {
        $ERR = "TAPE: getWWN: cannot identify $name on $host";
        return undef;
     } else {
        return $rc;
     }
  }
}

sub FCCounters {
  my($class ,$arg) = @_;

  my($renv) = System->get_renv();
  my($TO)   = $renv->{'timeout.luxadm'};
  my $PATHS = Luxadm->luxadmDiskPaths({type => "Tape"} );

  my (%W, %HBA, %D);
  foreach my $p (@$PATHS) {
     $W{$p->[1]} = 1;
     $HBA{$p->[0]} =1;
  }
  foreach my $w (keys %W) {
    next if ($w =~ /SUNW,socal/);
    my ($err, $rdls) = Util->run_command("/usr/sbin/luxadm -e rdls $w", "", $TO, {cache => 0});

    foreach my $l (@$rdls) {
      my(@c) = split(/\s+/, $l);
      next if ("$c[1]$c[2]" !~ /^\d+$/);
      $D{"|$w|port.1|tape"} = "$c[1]\t$c[3]\t$c[4]\t$c[6]\t$c[2]\t$c[5]";
    }
  }
# ${link} ${signal} ${seq} ${crc} $al2 ->{sync} ${word}

  my $out = { data => \%D,  hba => \%HBA };
  return $out;
}


sub get_WWN {
  my($q) = @_;
  my $name = $q->{name};

  my($err,$com) = Util->run_command("/usr/sbin/luxadm display $name 2>&1", 
                          "luxadm.txt" , 30);
  if ($err) {
    $q->{HTTP}? print $err : return $err;
  }
    
  my $out = "@$com";
  $out =~ /Node WWN:([0-9a-f]+)/;
  my $wwn = $1;
  $q->{HTTP}? print $wwn : return $wwn;
}

  

sub luxadm {
  my($agent, $device, $lux) = @_;
  my(@s, %dev, $in, %info, $key, $state, $num);
  my($v3, $v1, $v2, $x, $wwn, $status, $rev, $ib, $no, $id);

  if (System->get_testMode()) {
     my $testrep = Report->readTest($device);
     return ($device->{wwn}, "", $testrep);
  }
  my $renv = System->get_renv();
  my($TO) = $renv->{'timeout.luxadm'};
  Timelapse->startDev( $device);

  my $w = $device->{key} || $device->{name};
  my($err,$com) = Util->run_command("$lux display $w 2>&1", "luxadm.txt" , $TO);
  return ("",$err, undef) if ($err);

  my $disk_done = 0;

  foreach my $l (@$com) {
    if ($l =~ /^ *Error:/) {
       return ("",$l, undef);
    }   
    my($h1, $h2);
    if ($l =~ /(.*):\s+(.*)/) {
       $h1 = $1; $h2 = $2;
       if ($h1 =~ /Status\(Port (\w)\)/) {
         $info{"port.$1.status"} = $h2;

       } elsif ($h1 =~ /Path status/) {
	 $info{"port.A.status"} = $h2;

       } elsif ($h1 =~ /Vendor/) {
         $info{'info.vendor'} = $h2;

       } elsif ($h1 =~ /Product/) {
         $info{'info.productId'} = $h2;

       } elsif ($h1 =~ /WWN\(Port (\w)\)/) {
         $info{"port.$1.wwn"} = $h2;

       } elsif ($h1 =~ /LUN path port WWN/) {
         $info{"port.A.wwn"} = $h2;

       } elsif ($h1 =~ /Revision/) {
         $info{'info.revision'} = $h2;

       } elsif ($h1 =~ /Serial/) {
         $info{'info.serial'} = $h2;

       } elsif ($h1 =~ /Device Ty/) {
         $info{'info.deviceType'} = $h2;
       }
    }
   }
  return ("","Failed to probe this Tape" , undef) if (!$info{'info.vendor'});

  $agent->addIdentification(\%info);
  Debug->dump('tapeConfig', \%info);
  Timelapse->stopDev( $device);
  return ($device->{wwn}, "", \%info);
}

sub FRUS {
  my($class, $r, $name) = @_;
  my($v) = $r->{_value};
  my (@FRUS, $x);
  my $devtype = $r->category();
  push(@FRUS, [$name, $devtype, "tape","tape",
                $v->{'info.vendor'},       
                $v->{'info.productId'},       
                $v->{'info.serial'},       
                $v->{'info.revision'},       
                $v->{'port.A.status'}]);

  return \@FRUS;

}

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

  my($out);
  my($tableCnt) = $arg->{tableCnt};
  my($rev)      = $r->{'_value'}{"info.revision"};
  my($host0)    = $host || System->hostname();
  my($v)        = $r->{_value};
  my $c = "#CCCCFF";
  $out .= $class->reportHead("TAPE", $r);
  $out .= "
   <tr><td bgcolor=$c align=right><b>Name:</td><td width=25%>&nbsp;$r->{_id}{name}</td>
       <td bgcolor=$c align=right><b>Monitored on:</td><td>&nbsp;$host0</td>
  
   <tr>
       <td bgcolor=$c align=right><b>Rev:</td><td>&nbsp;$rev</td>
       <td bgcolor=$c align=right><b>WWN:</td><td>&nbsp;$r->{_id}{deviceName}</td>

   <tr>
       <td bgcolor=$c align=right><b>ProductID:</td><td>&nbsp;$v->{'info.productId'}</td>
       <td bgcolor=$c align=right><b>Type:</td><td nowrap>&nbsp;$v->{'info.deviceType'}</td>
   <tr>
       <td bgcolor=$c align=right><b>Vendor:</td><td>&nbsp;$v->{'info.vendor'}</td>
       <td bgcolor=$c align=right><b>Serial:</td><td>&nbsp;$v->{'info.serial'}</td>

   <tr>
       <td bgcolor=$c align=right><b>PortA.status:</td><td>&nbsp;$v->{'port.A.status'}</td>
       <td bgcolor=$c align=right><b>PortA.wwn:</td><td>&nbsp;$v->{'port.A.wwn'}</td>

  </table>
  
  ";
  $out .= "</table>\n";
  return $out;

}



1;

