package Revision::5210;
#<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::5210;
use PDM::ConfigFile;

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

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


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 "5210");
      next if (!Util->isMineToMonitor($dev));
      my ($wwn, $err, $report) = Agent::5210->INSTRUMENTATION($dev);
      if ($err eq "BUSY") {
         my $info = "The 5210 device is busy, please run revision check later";
         push(@R,['5210', $dev->{name}, 'ERR', undef, undef,undef,undef, $info]);
      } elsif ($err =~ /not accessible/){
         my $info = "The 5210 device is not accessible, please check system setup ";
         push(@R,['5210', $dev->{name}, 'ERR', undef, undef,undef,undef, $info]); 
      } else {
         my $r1 = $class->REVISION($Matrix, $InstalledPatches, $dev, $report);
         push(@R, @$r1);
      }
  }
  if ($#R < 0) {
      push(@R,['5210', 'N/A', 'ERR', undef, undef,undef,undef,"No 5210 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->{5210};    # used for stand alone 3310 
  my ($vendor, $model, $tem2, $firm_rev);
  # my $se_version = System::get_se_version();

  my $dev_type = "5210";

  my $firm_rev = $rep->{'controller.1.RaidCtlrFirmwareVersion'};
  my $firm_rev2 = $rep->{'controller.2.RaidCtlrFirmwareVersion'};
  my (@firmAry);
  @firmAry = split(/\s+/, $firm_rev);

  my (@firmAry2);
  @firmAry2 = split(/\s+/, $firm_rev2);

  if ($firmAry[0]) {
    my $firmware_info = $firmAry[0];
    push(@R, $class->check_firmware("5210_Controller_FW",undef, $firmware_info, $dev, $mat, "controller.1.firmrev"));

  } 
  
  if ($firmAry[1]) {       
    my $bios = $firmAry[1]; 
    push(@R, $class->check_firmware("5210_Controller_FW",undef, $bios, $dev, $mat, "controller.1.bios"));
 
  }

  # For 2nd Controller
  if ($firmAry2[0]) {
    my $firmware_info = $firmAry2[0];
    push(@R, $class->check_firmware("5210_Controller_FW",undef, $firmware_info, $dev, $mat, "controller.2.firmrev"));

  } 
  
  if ($firmAry2[1]) {       
    my $bios = $firmAry2[1]; 
    push(@R, $class->check_firmware("5210_Controller_FW",undef, $bios, $dev, $mat, "controller.2.bios"));
 
  }


  my $os_rev = $rep->{'info.OsVersion'};
  if ($os_rev) {
    push(@R, $class->check_firmware("5210_OS_VERISON",undef, $os_rev, $dev, $mat, "osversion")); 
  }
 
  foreach my $el (keys %$rep) {
      if (($el =~ /physicaldrive/) && ($el =~ /RaidPhysicalDriveType/)) {
         my $ix = rindex($el, ".");
         my $pre = substr($el, 0, $ix);
         my $vendor = $rep->{"$pre.RaidPhysicalDriveVendor"};
         my $model  = $rep->{"$pre.RaidPhysicalDriveModel"};
         my $val    = $rep->{"$pre.RaidPhysDriveFwRevision"};

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

     }
  }

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

sub check_firmware {
   my($class, $key, $elem, $val, $dev, $mat, $type, $info) = @_;

   my $default_info = "No patch available, please contact your SUN representative";

   my $el  = $mat->{$type};
   my $lastDot = rindex($type, ".");
   if ($lastDot) {
      my $subType = substr($type, $lastDot+1);
      $el  = $mat->{$subType};
   }

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

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

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

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

   } else {
       return [$key, "$comp.$type", '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 "-") && ($char ne ":")) { 
            if ( $char =~ /[a-zA-Z]/ ) {
               $m .= ord($char);
            }
            else {
               $m .= $char;
            }
       }
    }

    foreach my $char (@drive) {
       if (($char ne ".") && ( $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_5210 {
     my($class,$Matrix, $InstalledP,$vendor, $model, $val, $dev,$elem ,$dev_type) = @_;
     my $disk_fw;
     $disk_fw = $Matrix->{DISK_FW};

     my $category = "5210_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->compFwLevels($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;

