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

#  $Name: bld21_017 $ 
#  $Id: 3310.pm,v 1.11 2005/01/26 16:59:54 zhangy Exp $

use Report;
use CIM::Instance;

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

sub newSystem {
  my ($class, $rep) = @_;
  my(@pil, $i, $dd, $a, $j, $k, $k1, $v);
  my $CTRL;
  my $wwn  = $rep->get('id.key'); # really the key now
  my $renv = System->get_renv();
  my $type = $rep->get("id.device_type");
  # info.total_power, info.total_ctrl, info.total_disk
  my $disks = $rep->get("info.total_disk");
  my $ctrl  = $rep->get("info.total_ctrl");
  my $power = $rep->get("info.total_power");
  my $other = $rep->get("info.total_other");
  my $cache = $rep->get("info.cache_size");

  my($p1) = CIM::Instance->new('NWS_System',[
                    [Name 		=> $wwn ],
                    [OtherIdentifyingInfo => $rep->get("info.name") ],
                    [FruCount           => $other + $disks + $ctrl + $power  ],
                    [FruCtlrCount       => $ctrl   ],
                    [FruDiskDriveCount  => $disks  ],
                    [FruLoopCount       => $ctrl   ],
                    [FruPowerCount      => $power  ],
                    [Cache              => $cache  ],
                    [SystemName         => $rep->get('id.name')],
                    [IP 		=> $rep->get('id.ipno')],
                    [VolCount 		=> $rep->get('info.total_logical_drives')],
                    [SysRevision 	=> $rep->get('info.Revision')],
                    [Caption            => $type] ,
                ]);

  my($p2) = CIM::Instance->new('CIM_PhysicalFrame', [
                  [Tag 			=> $wwn],
                  [Name			=> $wwn],
                  [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);

  my $topdisk = $rep->get('info.top_disk');

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

  for ($j = 0; $j <= $topdisk; $j++) {
      next if (!$rep->get("components.disk.$j.model"));
      $dd = $class->newDiskDrive($rep,"components.disk.$j");
      next if (!$dd);
      $a = CIM::Instance->new('CIM_Container', [
                   [GroupComponent  => $p2],
                   [PartComponent => $dd->[1]],
                   [LocationWithinContainer => "components.disk.$j"],
                   ]);
      push (@pil, @$dd, $a);

      # Save the disks in a hash for associating with the logical drives
      # when they are created.
      my $diskCH = $rep->get("components.disk.$j.ch");
      my $diskEN = $rep->get("components.disk.$j.target");
      my $diskID = $diskCH . "\." . $diskEN;

      $diskDriveInstances{$diskID} = $dd;

  }

  my $LUNS =  $rep->get('info.total_logical_drives');

  # Search through the report for logical_drives and FRUs.
  foreach my $el (keys %$rep)
  {
     # If this is of the pattern logical_drive.<pattern>.ld_id
     # Then create a new LUN instance for it.
     if ($el =~ /^logical_drive\.(\w+)\.ld_idx/) 
     {
        my $ldIndex = $1;

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

        # Create an association between the drive and the logical drive
        my $physicalDrives = $rep->get("logical_drive.$ldIndex.physical_drive");
        my @driveList = split(/\s+/, $physicalDrives);

        foreach my $diskDrive (@driveList) 
        {
           my $diskDriveInst = $diskDriveInstances{$diskDrive};
           next if (!$diskDriveInst);
           my $ldToDiskAssoc =  CIM::Instance->new('CIM_MediaPresent', [
                                 [Antecedent => $diskDriveInst->[0] ],
                                 [Dependent  => $dd->[0] ],
                                 ]);

           push (@pil, $ldToDiskAssoc);

        }
     }

     # If this is of the pattern logical_volume.<pattern>.lv_id
     # Then create a new LUN instance for it.
     if ($el =~ /^logical_volume\.(\w+)\.lv_idx/)
     {
        my $lvIndex = $1;

        $dd = $class->newVolume($rep,"logical_volume.$lvIndex");
        next if (!$dd->[0]);
        my $v2 =  CIM::Instance->new('CIM_MediaPresent', [
                          [Antecedent => $p1 ],
                          [Dependent  => $dd->[0] ],
                          ]);
        push (@pil, @$dd, $v2);

     }

     # If this is of the pattern fru.<pattern>.name
     # Then create a new fru instance for it.
     elsif ($el =~ /^fru\.(\w+)\.name/) 
     {
        my $fruID = $1;
        my $location = $rep->get("fru.$fruID.fru_location"); 
        $dd = $class->newFru($rep,"fru.$fruID");
        if ($dd)
	{
           $a = CIM::Instance->new('CIM_Container', [
                        [GroupComponent  => $p2],
                        [PartComponent => $dd->[1]],
                        [LocationWithinContainer => $location],
                        ]);		
           push (@pil, @$dd, $a);
	}

     }

  }
 
  return Ilist->new(\@pil);

}

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

sub fruKey {
  my($class, $rep, $cd) = @_;
  my $partnum = $rep->get("$cd.part_number");
  my $serialnum = $rep->get("$cd.serial_number");
  #if ((!exists ($partnum) ) && ( !exist ($serialnum))) {
  #   return undef;
  #} 
  return  $partnum . "." . $serialnum ;
}

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

  my($map) = PDM->getDeviceStateMap("3310.availability");
  my $state = $map->get("status." . $rep->get("$cd.Status"));
  return $state;
}

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

  my($serial_no) = $class->fruKey($rep, $cd);

  return undef if (!$serial_no);
  my $status  = "OK";
  my $info = $rep->get("$cd.manufacturing_date") . ", " . 
             $rep->get("$cd.manufacturing_location");

  my $item = $rep->get("$cd.name") || $rep->get("$cd.item");
  my $NWS;
  my $id = $rep->get("$cd.fru_location") || $cd;
  $id =~ s/ /_/g;
  my $manuf = $rep->get("$cd.manufacturer_jedec_id") || "SUN";

  $p1 = CIM::Instance->new("NWS_Fru", [
                [SystemName 	    => $item     ],
                [DeviceID 	    => $serial_no],
                [Name     	    => $serial_no],
                [Status             => "NA"  ],
                [Type               => $item ],
                [FruId              => $id   ],
                [OtherIdentifyingInfo => $rep->get("$cd.description") ],
                 ]);
  push(@il,$p1);
  $c1 = CIM::Instance->new('CIM_Card', [
                [Removable     => "Yes"],
                [Tag	        => $serial_no],
                [Name    	=> $serial_no],
                [SerialNumber 	=> $rep->get("$cd.serial_number") ],
                [Manufacturer 	=> $manuf    ],
                [Model 		=> $rep->get("$cd.part_number")],  
                [Version 	=> $rep->get("$cd.revision")],  
                    ]);


  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);

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

  $p1 = CIM::Instance->new('NWS_DiskDrive', [
                [SystemName 	    => $rep->get("$cd.manufacturer")." DiskDrive"],
                [DeviceID 	    => $serial_no],
                [Name     	    => $serial_no],
                [FruDiskCapacity    => $rep->get("$cd.capacity")],
                [StatusInfo         => $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.serial_number") ],
                [Manufacturer 	=> $rep->get("$cd.manufacturer")],  
                [Model 		=> $rep->get("$cd.model")],  
                [Version 	=> $rep->get("$cd.product_revision")],  
                    ]);

  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, $cd) = @_;
  my @pil;
  my $wwn =  $rep->{"id.key"} . ".$cd";
  my $v1 = CIM::Instance->new('NWS_StorageVolume', [
                  [ SystemName      => $wwn ],
                  [ DeviceID        => $wwn ],
                  [ VolWWN          => $wwn ],
                  [ VolId           => $cd  ],
                  [ VolRaidLevel    => $rep->{"$cd.raid_level"} ],
                  [ VolName         => $rep->{"$cd.ld_id"} ],
                  [ Capacity        => $rep->{"$cd.size"} ],
                  [ VolStatus       => $rep->{"$cd.status"}   ],
                         ]);

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


# note: 1) no raid level for volume in minnow
#       2) lv_id is used for name instead of ld_id

sub newVolume {
  my($class, $rep, $cd) = @_;
  my @pil;
  my $wwn =  $rep->{"id.key"} . ".$cd";
  my $v1 = CIM::Instance->new('NWS_StorageVolume', [
                  [ SystemName      => $wwn ],
                  [ DeviceID        => $wwn ],
                  [ VolWWN          => $wwn ],
                  [ VolId           => $cd  ],
                  [ VolRaidLevel    => undef ],
                  [ VolName         => $rep->{"$cd.lv_id"} ],
                  [ Capacity        => $rep->{"$cd.size"} ],
                  [ VolStatus       => $rep->{"$cd.status"}   ],
                         ]);

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


1;
