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

#  $Name: Keyur Desai 
#  $Id: 5210.pm,v 1.10 2005/04/21 21:29:18 kdesai Exp $

use Report;
use CIM::Instance;

use Data::Dumper;
use strict;
use Ilist;
use PDM;
use NWS;
sub revision {'$Revision: 1.10 $'}
sub category {"5210"}

sub newSystem {
  my ($class, $rep) = @_;
  my(@pil, $i, $dd, $a, $j, $k, $k1, $v, $pt);
  my $CTRL;
  my $sn1  = $rep->get('id.device_key'); # really the key now
  my $renv = System->get_renv();
  my $type = $rep->get("id.device_type");
  my $sn = "$type.$sn1";


  my($p1) = CIM::Instance->new('NWS_System',[
                    [Name 		=> $sn ],
                    [OtherIdentifyingInfo => $type ],
                    [SystemName         => $rep->get('id.device_name')],
                    [IP 		=> $rep->get('id.device_ip')],
                    [SysRevision 	=> $rep->get('controller.1.RaidCtlrFirmwareVersion')],
                    [Caption            => $type],
		    [VolCount		=> $rep->get('info.totalLogicalDiskDrive')], 
                ]);

  my($p2) = CIM::Instance->new('CIM_PhysicalFrame', [
                  [Tag 			=> $sn],
                  [Name			=> $sn],
                  [Manufacturer 	=> "SUN"  ],
                  [Model 		=> $type  ],
                  ]);

  my($a2) = CIM::Instance->new('CIM_ComputerSystemPackage', [
                  [Antecedent          => $p1],
                  [Dependent           => $p2],
                  ]);

  my($l1) = NWS->location($rep);
  
  my($al1) = CIM::Instance->new('NWS_PhysicalFrameLocation', [
                  [Element 		=> $p2],
                  [PhysicalLocation 	=> $l1],
                  ]);
               
  push (@pil, $p1, $p2, $a2, $l1, $al1);

  # Hash for drive to lun (logicalDisk) mapping
  my %diskDriveInstances;

  foreach my $el (keys %$rep) {
     
     if (($el =~ /^physicaldrive.(\d)-(\d+).RaidPhysicalDriveModel/) ||
         ($el =~ /^physicaldrive.(\d)-(\d)-(\d+).RaidPhysicalDriveModel/)) {

       my ($controllerID, $channelID, $targetID, $driveIndx);

       if ($3) {
	    $controllerID = $1;
 	    $channelID = $2;
            $targetID = $3;
	    $driveIndx = $controllerID."-".$channelID ."-" .$targetID;	    	    
       } else {
 	    $channelID = $1;
            $targetID = $2;
	    $driveIndx = $channelID ."-" .$targetID;
       }

       $dd = $class->newDiskDrive($rep,"physicaldrive.$driveIndx");
       next if (!$dd);
       
       $a = CIM::Instance->new('CIM_Container', [
             [GroupComponent  => $p2],
             [PartComponent => $dd->[1]],
             [LocationWithinContainer => "physicaldrive.$driveIndx"],
           ]);
       push (@pil, @$dd, $a);

       # Save the disks in a hash for associating with the logical drives
       # when they are created.
       my $disklunName =  $rep->get("physicaldrive.$driveIndx.RaidPhysicalDriveLunName");

       $diskDriveInstances{"$disklunName.$driveIndx"} = $dd;

     } elsif ( ($el =~ /^(\w+)\.(\d)\.RaidPowerSupplyStatus/) ||
               ($el =~ /^(\w+)\.(\d)\.RaidFanStatus/) ||
	       ($el =~ /^(\w+)\.(\d)\.RaidBBUStatus/) ||
	       ($el =~ /^(\w+)\.(\d)\.RaidControllerStatus/) ||
	       ($el =~ /^(\w+)\.(\d)\.EnvPowerStatus/) ||
               ($el =~ /^(\w+)\.(\d)\.EnvFanStatus/) ||
	       ($el =~ /^(\w+)\.(\d)-(\d)\.RaidPowerSupplyStatus/) ||
               ($el =~ /^(\w+)\.(\d)-(\d)\.RaidFanStatus/) ||
	       ($el =~ /^(\w+)\.(\d)-(\d)\.RaidBBUStatus/) ||
	       ($el =~ /^(\w+)\.(\d)-(\d)\.RaidControllerStatus/) ||
	       ($el =~ /^(\w+)\.(\d)-(\d)\.EnvPowerStatus/) ||
               ($el =~ /^(\w+)\.(\d)-(\d)\.EnvFanStatus/)) {  

       my $fruId;
       if ($3) {
         $fruId = "$1.$2-$3";
       } else {
	 $fruId = "$1.$2";
       }  

       my $nFru = $class->newFru($rep,"$fruId");
       next if (!$nFru);
       $a = CIM::Instance->new('CIM_Container', [
                   [GroupComponent  => $p2],
                   [PartComponent => $nFru->[1]],
                   [LocationWithinContainer => "$fruId"],
                   ]);
       push (@pil, @$nFru, $a);
     }  
  }   
  
  # If this is of the pattern logical_drive.<decimal>.ld_id
  # Then create a new LUN instance for it.
  my $totalLuns = $rep->get("info.totalLogicalDiskDrive");
  my $diskInstances = \%diskDriveInstances;
  my($key, $value);
  for ($j = 1; $j <= $totalLuns; $j++) { 
     my $ldIndex = $j;

     my $ld = $class->newLun($rep,"logicaldrive.$ldIndex");
     my $v2 =  CIM::Instance->new('CIM_MediaPresent', [
                          [Antecedent => $p1 ],
                          [Dependent  => $ld->[0] ],
                          ]);
     push (@pil, @$ld, $v2);


     # Create an association between the drive and the logical drive
     my $logicalDriveName = $rep->get("logicaldrive.$ldIndex.RaidSystemDriveName");

     while (($key, $value) = each %$diskInstances) {

 	 my @D = split(/\./, $key);
	 my $diskLunName = $D[0]; 
         
	 if ($logicalDriveName eq $diskLunName) {

             my $ldToDiskAssoc =  CIM::Instance->new('CIM_MediaPresent', [
                                 [Antecedent => $value->[0] ],
                                 [Dependent  => $ld->[0] ],
                                 ]);

             push (@pil, $ldToDiskAssoc);
	 }
     }
  }

  # Partition
  my $totalPartitions = $rep->get("info.totalPartition");
  for ($j = 1; $j <= $totalPartitions; $j++) {
     my $pIndex = $j;

     my $ld = $class->newLun($rep,"partition.$pIndex");
     my $v2 =  CIM::Instance->new('CIM_MediaPresent', [
                          [Antecedent => $p1 ],
                          [Dependent  => $ld->[0] ],
                          ]);
     push (@pil, @$ld, $v2);

     # Add code for Partition association to LUN when we have that info.
  }
     
  return Ilist->new(\@pil);

}


sub getKey {
  my($class, $rep, $cd) = @_;
  return "" if (!$rep->get("$cd.RaidPhysicalDriveModel"));
  return  $rep->get("$cd.RaidPhysicalDriveVendor").".".$rep->get("$cd.RaidPhysicalDriveModel").".".$rep->get("$cd.RaidPhysicalDriveSerial");
}


sub fruKey {
  my($class, $rep, $cd) = @_;

  my $sn1  = $rep->get('id.device_key'); # really the key now
  my $type = $rep->get("id.device_type");
  my $sn = "$type.$sn1";

  # For now use the System Serial Number till we fix the bug to get serial for FRU's  
  return  $sn.".".$cd;

}

sub getFRUStatus {

  my ($class, $fruType, $comp, $rep) = @_;

  if ($fruType eq "fan") {
      return $rep->get("$comp.RaidFanStatus");
  } elsif ($fruType eq "powersupply") {
      return $rep->get("$comp.RaidPowerSupplyStatus");
  } elsif ($fruType eq "environment_ps") {
      return $rep->get("$comp.EnvPowerStatus");
  } elsif ($fruType eq "environment_fn") {
      return $rep->get("$comp.EnvFanStatus");
  } elsif ($fruType eq "controller") {
      return $rep->get("$comp.RaidControllerStatus");
  } elsif ($fruType eq "battery") {
      return $rep->get("$comp.RaidBBUStatus");
  } else {
      return "NA";
  }     
  
}

sub newFru {
  my($class, $rep, $cd) = @_;
  my(@il, $p1, $c1, $a1, $c2, $a2);

  my $sn = $rep->get("id.device_key");
  my $type = $rep->get("id.device_type");
  my($serial_no) = $class->fruKey($rep, $cd);

  return undef if (!$serial_no);

  my $id = $cd;
  $id =~ s/ /_/g;
  my $manuf = "SUN";
  
  my @L = split(/\./, $cd);
  my $fruType = $L[0];
  my $status  = $class->getFRUStatus($fruType, $cd, $rep);

  $p1 = CIM::Instance->new("NWS_Fru", [
                [SystemName 	    => "$type.$sn"],
                [DeviceID 	    => $serial_no],
                [Name     	    => $serial_no],
                [Status             => $status  ],
                [Type               => $fruType ],
                [FruId              => $cd   ],
                [OtherIdentifyingInfo => $fruType ],
                 ]);
  push(@il,$p1);
  $c1 = CIM::Instance->new('CIM_Card', [
                [Removable     => "Yes"],
                [Tag	        => $serial_no],
                [Name    	=> $serial_no],
                [SerialNumber 	=> $serial_no ],
                [Manufacturer 	=> $manuf     ],
                [Model 		=> $serial_no ],  
                [Version 	=> $serial_no ],  
                    ]);


  push(@il, $c1);
  $a1 = CIM::Instance->new('CIM_Realizes', [
                    [Antecedent => $c1],
                    [Dependent => $p1],
                    ]);
                    
  push(@il,$a1);

  return Ilist->new(\@il);

}


sub newDiskDrive {
  my($class, $rep, $cd) = @_;
  my(@il, $p1, $c1, $a1, $c2, $a2);

  my($serial_no) = $class->getKey($rep, $cd);
  my $sn = $rep->get("id.device_key");

  return undef if (!$serial_no);
  my($status) = $rep->get("$cd.RaidPhysicalDriveStatus");

  $p1 = CIM::Instance->new('NWS_DiskDrive', [
                [SystemName 	    => "physicalDiskDrive"], # SystemName = Type for Disk Drive
                [DeviceID 	    => $serial_no],
                [Name     	    => $serial_no],
                [FruDiskCapacity    => $rep->get("$cd.RaidPhysicalDriveSize")],
                [StatusInfo         => $status],
                [Status             => $status], #$class->getState($rep, $cd)],
                 ]);
  push(@il,$p1);

  $c1 = CIM::Instance->new('CIM_PhysicalPackage', [
                [Removable 	=> "Yes"],
                [Tag 	        => $serial_no],
                [Name    	=> $serial_no],
                [SerialNumber 	=> $rep->get("$cd.RaidPhysicalDriveSerial") ],
                [Manufacturer 	=> $rep->get("$cd.RaidPhysicalDriveVendor") ],  
                [Model 		=> $rep->get("$cd.RaidPhysicalDriveModel") ],  
                [Version 	=> $rep->get("$cd.RaidPhysDriveFwRevision") ],  
                    ]);

  push(@il, $c1);
  $a1 = CIM::Instance->new('CIM_Realizes', [
                    [Antecedent => $c1],
                    [Dependent => $p1],
                    ]);
                    
  push(@il,$a1);

  return Ilist->new(\@il);

}

# logical.2 

sub newLun {
  my($class, $rep, $lunid) = @_;
  my @pil;
  my $sn = $rep->get("id.device_key");
  my $type = $rep->get("id.device_type");
  my $cd = $lunid;

  my $v1 = CIM::Instance->new('NWS_StorageVolume', [
                  [ SystemName      => "$type.$sn" ],
                  [ DeviceID        => "$type.$sn.$lunid" ],
		  [ Name            => $rep->{"$cd.RaidSystemDriveName"} || $rep->{"$cd.PartitionMountPoint"}],
                  [ VolWWN          => $rep->{"$cd.RaidSystemDriveName"} || $rep->{"$cd.PartitionMountPoint"} ],
                  [ VolId           => $rep->{"$cd.RaidSystemDriveName"} || $rep->{"$cd.PartitionMountPoint"} ],
                  [ VolRaidLevel    => $rep->{"$cd.RaidSystemDriveRaidLevel"} ],
                  [ VolName         => $rep->{"$cd.RaidSystemDriveName"} || $rep->{"$cd.PartitionMountPoint"}],
                  [ Capacity        => $rep->{"$cd.RaidSystemDriveSize"} || $rep->{"$cd.PartitionSize"}],
                  [ VolStatus       => $rep->{"$cd.RaidSystemDriveStatus"} || $rep->{"$cd.PartitionMode"} ],
                         ]);

   push(@pil, $v1);
   return Ilist->new(\@pil);
}

1;

