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

use strict;
use base 'Revision';
use System;
use Util;
use Agent::6130;
use PDM::ConfigFile;

#
#  PASS, LOW, HIGH, NI (not installed), ERR

sub class {"oob.6130"}
sub description {"Sun StorEdge 6130 array"}
sub type {"6130"}


sub RUN {
  my($class, $Matrix, $InstalledPatches) = @_;
  my(@R);

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

  foreach my $dev (@$devs) {
      next if ($dev->{type} ne "6130");
      next if (!Util->isMineToMonitor($dev));
		my $lockerr = $class->checkLock($dev);
		if ($lockerr){
		  push(@R, $lockerr);
		}
		else {
		  my $report = Agent::6130->INSTRUMENTATION($dev);
		  my $r1 = $class->REVISION($Matrix, $InstalledPatches, $dev, $report);
		  push(@R, @$r1);
		}

  }
  if ($#R < 0) {
      push(@R,['6130', 'N/A', 'ERR', undef, undef,undef,undef,"No 6130 device, please check system setup"]);
  }
  return \@R;
  
}

# runs on only one device, dev is from the configFile
#
sub REVISION {
  my( $class, $Matrix, $InstalledPatches, $dev, $rep) = @_;
  my ( $mat, @R , @R1);
  my $mat = $Matrix->{6130};    # used for stand alone 6130 
  my ($vendor, $model, $tem2, $firm_rev);
  # my $se_version = System::get_se_version();

  my $dev_type = "6130";

  # Check for controller firmware
  my $firm_rev = $rep->{'system._Version'};
  push(@R, $class->check_firmware("6130_Controller_FW",undef, $firm_rev, $dev, $mat, "firmrev", "firmrev"));

  
  # Check for NVS RAM firmware
  my $nvs_firm_rev = $rep->{'system.nvsram'};
#  push(@R, $class->check_firmware("6130_NVSRAM_FW",undef, $nvs_firm_rev, $dev, $mat, "nvsram", "nvsram"));
  push(@R, $class->devCompare("6130_NVSRAM_FW",undef, $nvs_firm_rev, $dev, $mat, "nvsram"));

  
  foreach my $el (keys %$rep) {
      if ($el =~ /fru\.(\d+)\._Type/) {
         my $ix = $1;
	 my $pre = "fru.$ix";
	 my $type = $rep->{"$pre._Type"};

	 if ($type =~ /Disk/) {

             my $vendor = Util->trim($rep->{"$pre._Vendor"});
             my $model  = $rep->{"$pre._Model"};
             my $val    = $rep->{"$pre._Firmware"};
	     my $name   = $rep->{"$pre._name"};
	     my $pre    = "Disk.$ix";

	     foreach my $eli (keys %$rep) {
	        if ($eli =~ /disk\.(\d+)\._Realized/) {
		     my $diskID = $1;
		     my $diskPre = "disk.$diskID";
		     my $diskName = $rep->{"$diskPre._Realized"};
		     if ($diskName eq $name) {
		         $pre    = $rep->{"$diskPre._ElementName"};    
		     }
		} 
	     }

             if ($model) {  #  $model= '' means dummy disk, skip it
                push(@R1,$class->checkDiskFirmware_6130($Matrix, $InstalledPatches, $vendor, $model, $val,$dev,$pre,$dev_type));
             }
	 }

         # Check IOM firmware (Note: $pre is the fru prefix ie. fru.7)
	 elsif ($type =~ /IOM/)
	 {
	    my $iom_firm_rev = $rep->{"$pre._Firmware"};
	    my $name         = $rep->{"$pre._name"};
	    my $displayName  = $name; # vendor.model.sn is better than nothing.  It should be changed below.

	    my $category  = "iom";
            
	    MATCHLOOP: foreach my $eli (keys %$rep) 
	    {
	       if ($eli =~ /iom\.(\d+)\._Realized/) 
	       {
		   my $iomID = $1;
		   my $iomPre = "iom.$iomID";
		   my $iomName = $rep->{"$iomPre._Realized"};
		   if ($iomName eq $name) 
		   {
		      $displayName  = $rep->{"$iomPre._ElementName"};

		      my $iomtype   = lc($rep->{"$iomPre.type"});

		      if (($iomtype =~ /sata/) || ($iomtype =~ /sbod/))
		      {
	                 $category  = "iom-$iomtype";
		      }

    		      last MATCHLOOP; # like a break
		   }
	       }
	    }
	    
	    push(@R, $class->check_firmware("6130_IOM_FW",undef, $iom_firm_rev, $dev, $mat, $category, $displayName));
	 }

     }
  }

  my @SR1 = sort { $a->[1] cmp $b->[1] } @R1 ;
 
  push (@R, @SR1);
  return \@R;
}

# suffix is the instance identifier
sub check_firmware {
   my($class, $key, $elem, $val, $dev, $mat, $type, $suffix, $info) = @_;

   my $default_info = "no patch information available, please contact your sun representative";
   my $el  = $mat->{$type};

   my $rev   = $el->[0];
   my $patch = $el->[1];
   my $desc  = $el->[2];
   my $comp = ($dev->{name} || $dev->{ip});

   if (!$el) {
       return [$key, "$comp.$suffix", 'ERR' , undef, undef, undef , $patch,
          "No entry in Matrix for $key.$suffix" ];
   }
   if ($val < 0) {
       return [$key, "$comp.$suffix.$elem", 'ERR' , undef, undef, undef , undef, "Revision is not available" ];
   }

   my $cp = $class->compFwLevels($val, $rev);
   if ($cp > 0) {
         if (( $patch =~ /xxxx/ ) && ( !$info ) ) {
            return [$key, "$comp.$suffix", 'UPREV' , $val, $rev, undef , "N/A", $default_info];
         } else {
            return [$key, "$comp.$suffix", 'UPREV' , $val, $rev, undef, $patch, $info];
         }

   } elsif ($cp < 0) {
          if (( $patch =~ /xxxx/ ) && ( !$info ) ){
             return [$key, "$comp.$suffix",'DOWNREV' , $val, $rev, undef , "N/A", $default_info];
          } else {
             return [$key, "$comp.$suffix", 'DOWNREV' , $val, $rev, undef, $patch, $info];
          }

   } else {
       return [$key, "$comp.$suffix", 'PASS' , $val, $rev, undef , undef, $info];
   }
}

sub compFwLevels {
    my ($class, $drive, $matrix) = @_;
    my (@matrix, @drive);

    @matrix = split(//, $matrix); # separate characters
    @drive = split(//, $drive); # separate characters
    my ($m, $d);
    foreach my $char (@matrix) {
        if (($char ne ".") && ( $char ne "-")) { 
            if ( $char =~ /[a-zA-Z]/ ) {
               $m .= ord($char);
            }
            else {
               $m .= $char;
            }
       }
    }

    foreach my $char (@drive) {
       if (($char ne ".") && ( $char ne "-") ) {
            if ( $char =~ /[a-zA-Z]/ ) {
               $d .= ord($char);
            }
            else {
               $d .= $char;
            }
       }
    }

    if (hex($d) > hex($m)) {
        return 1;
    } elsif (hex($d) < hex($m)) {
        return -1;
    } else {
        return 0;
    }
}


sub checkDiskFirmware_6130 {
     my($class,$Matrix, $InstalledP,$vendor, $model, $val, $dev,$elem ,$dev_type) = @_;
     my $disk_fw;
     $disk_fw = $Matrix->{DISK_FW};

     my $category = "6130_DISK_FW";      

     my $key = "$vendor:$model:$dev_type";    # default set up

     my $curr_fw = $val;
     my $cp = ($dev->{name} || $dev->{ip});

     if ($disk_fw->{$key}) {
            my $d = $disk_fw->{$key};
            my $req_fw = $d->[0];
            my $req_patch = $d->[2];
            my $desc =  "$vendor:$model";
            my $info =  " No patch available, please contact your SUN representative ";
            my($req_base, $req_rev) = $class->baseRev($req_patch);
            if ($curr_fw < 0){
            return [$category, "$cp.$elem", 'ERR', undef, $req_fw, undef, $req_patch, "Unable to get the device firmware level, please contact you SUN representative"];
            }
            my $comp = $class->compareDiskFwLevels($curr_fw, $req_fw);
            if ($comp == 0) {
               if ( ($req_patch =~ /xxxx/) || ( !$req_patch ) ) {
                      return [$category, "$cp.$elem", 'PASS', $curr_fw, $req_fw, undef, undef, undef];
               } else {
                      return [$category, "$cp.$elem", 'PASS', $curr_fw, $req_fw, undef, $req_patch, $desc];
               }
            } elsif ($comp > 0) {
               if ( ($req_patch =~ /xxxx/) || ( !$req_patch ) ) {
                     return [$category,"$cp.$elem", 'UPREV', $curr_fw, $req_fw, undef, undef, $desc];
               } else {
                     return [$category, "$cp.$elem", 'UPREV', $curr_fw, $req_fw, undef, $req_patch, $desc];
               }
            } elsif ($comp < 0) {
               if ( ($req_patch =~ /xxxx/) || ( !$req_patch ) ) {
                    return [$category, "$cp.$elem", 'DOWNREV', $curr_fw, $req_fw, undef, "N/A", $info];
               } else {
                    return [$category, "$cp.$elem", 'DOWNREV', $curr_fw, $req_fw, undef, $req_patch, $desc];
               }
            }
            else {
              return [$category, "$cp.$elem", 'ERR', $curr_fw, $req_fw, undef, $req_patch, "Unable to check $vendor device,please contact your SUN representative and update the device firmware"];
            }
    } else {
           return [$category, "$cp.$elem", 'ERR', undef, undef, undef, undef, "Unable to check the $vendor device, please see sunsolve online for potential patch information or contact your SUN representative"];
    }

}

1;

