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

#  $Name:  $ 
#  $Id: T3.pm,v 1.13 2002/10/29 00:00:22 ccadieux Exp $

use Report;
use CIM::Instance;
use Data::Dumper;
use strict;
use Ilist;
use PDM;
use NWS;
sub revision {'$Revision: 1.13 $'}
sub category {"T3"}

sub newSystem {
  my ($class, $rep) = @_;
  my(@pil, $i, $dd, $a, $j, $k, $k1, $v);
  my $CTRL;
  my $wwn  = $rep->get('id.wwn'); # really the key now
  my $wwn1 = $rep->get('port.u1p1.portWWN');
  my $renv = System->get_renv();

  my($p1) = CIM::Instance->new('NWS_System',[
                    [Name 		=> $wwn ],
                    [OtherIdentifyingInfo  => "wwn=$wwn1" ],
                    [SystemName         => $rep->get('id.name')],
                    [LogInfo            => $rep->get('info.syslog')],
                    [IP 		=> $rep->get('system.sysIpAddr')],
                    [FruCount 		=> $rep->get('system.fruCount')],
                    [FruCtlrCount 	=> $rep->get('system.fruCtlrCount')],
                    [FruDiskDriveCount 	=> $rep->get('system.fruDiskCount')],
                    [FruLoopCount 	=> $rep->get('system.fruLoopCount')],
                    [FruPowerCount 	=> $rep->get('system.fruPowerCount')],
                    [VolCount 		=> $rep->get('system.volCount')],
                    [SysBootDelay 	=> $rep->get('system.sysBootDelay')],
                    [SysBootMode 	=> $rep->get('system.sysBootMode')],
                    [SysCacheMirror	=> $rep->get('system.sysCacheMirror')],
                    [SysCacheMode 	=> $rep->get('system.sysCacheMode')],
                    [SysRevision 	=> $rep->get('system.sysRevision')],
                    [Caption            => $class->category()],
                ]);

  my($p2) = CIM::Instance->new('CIM_PhysicalFrame', [
                  [Tag 			=> $wwn],
                  [Name			=> $wwn],
                  [Manufacturer 	=> $rep->get("system.sysVendor")],
                  [Model 		=> $rep->get("system.sysModel")],
                  ]);

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

  $CTRL =  $rep->get('controller.count');

  for ($i = 1; $i <= $CTRL; $i++) {
    $dd = $class->newController($rep,"controller.u${i}ctr", $i);
    next if (!$dd);
    $a = CIM::Instance->new('CIM_Container', [
                   [GroupComponent  => $p2],
                   [PartComponent => $dd->[1]],
                   [LocationWithinContainer => "controller.u${i}ctr"],
                   ]);
    push (@pil, @$dd);
    push (@pil, $a);

    $dd = $class->newMidplane($rep,"midplane.u${i}mpn");
    if ($dd) {
      $a = CIM::Instance->new('CIM_Container', [
                   [GroupComponent  => $p2],
                   [PartComponent => $dd->[1]],
                   [LocationWithinContainer => "midplane.u${i}mpn"],
                   ]);
 
      push (@pil, @$dd);
      push (@pil, $a);
    } else {
      Debug->err('T3_CIM_KEY', "midplane.u${i}mpn", $wwn);
    }

  }

  for ($i = 1; $i <= $CTRL; $i++) {
    for ($j = 1; $j <= 2; $j++) {
      $dd = $class->newPowerUnit($rep,"power.u${i}pcu$j");
      next if (!$dd);
      $a = CIM::Instance->new('CIM_Container', [
                   [GroupComponent  => $p2],
                   [PartComponent => $dd->[1]],
                   [LocationWithinContainer => "power.u${i}pcu$j"],
                   ]);
 
      push (@pil, @$dd);
      push (@pil, $a);
    }
  }

  for ($i = 1; $i <= $CTRL; $i++) {
    for ($j = 1; $j <= 2; $j++) {
      $dd = $class->newLoopCard($rep,"loopcard.u${i}l$j");
      next if (!$dd);
      $a = CIM::Instance->new('CIM_Container', [
                   [GroupComponent  => $p2],
                   [PartComponent => $dd->[1]],
                   [LocationWithinContainer => "loopcard.u${i}l$j"],
                   ]);
      push (@pil, @$dd);
      push (@pil, $a);
    }
  }

  my(@vols);
  my($volCnt) = 0;
  my(%DSK) = ();
  for ($i = 1; $i <= $CTRL; $i++) {
    for ($v=1; $v <= 2; $v++) { # see of volumes exist (max 2).
       if ($rep->get("volume.u${i}vol$v.volName")) {
          my($p) = "volume.u${i}vol$v";
          my $raid =  $rep->get("$p.volRaidLevel");
          $raid =~ s/raid//;
          $vols[$v] = CIM::Instance->new('NWS_StorageVolume', [
                    [ SystemName        => "Volume"         ],
                    [ DeviceID          => "$wwn.$p"     ],
                    [ Name              => "$wwn.$p"     ],
                    [ VolWWN            => substr($rep->get("$p.volWWN"),0,50) ],
                    [ VolName           => $rep->get("$p.volName") ],
                    [ VolErrors         => $rep->get("$p.volErrors") ],
                    [ VolFirmwareErrors => $rep->get("$p.volFirmErrors") ],
                    [ VolIndex          => $rep->get("$p.volIndex") ],
                    [ VolId             => $rep->get("$p.volId") ],
                    [ VolCacheMirror    => $rep->get("$p.volCacheMirror") ],
                    [ VolCacheMode      => $rep->get("$p.volCacheMode") ],
                    [ VolRaidLevel      => $raid ],
                    [ VolStatus         => $rep->get("$p.volStatus") ],
                    ]);
          push (@pil,$vols[$v] );
          $volCnt++;
        }
    }

    my $diskTotal = $rep->get('disk.count') || 9;
    for ($j = 1; $j<= $diskTotal; $j++) {
      $dd = $class->newDiskDrive($rep,"disk.u${i}d$j");
      next if (!$dd);
      $a = CIM::Instance->new('CIM_Container', [
                   [GroupComponent  => $p2],
                   [PartComponent => $dd->[1]],
                   [LocationWithinContainer => "disk.u${i}d$j"],
                   ]);
      $DSK{"u${i}d$j"} = $dd->[0];
      push (@pil, @$dd, $a);
    }
    
    for ($k1 = 1;$k1 <= $volCnt; $k1++) {
       for ($k=0; $k <= 8; $k++) {
          my($dfid) = $rep->get("volume_disk.u${i}vol${k1}-d-$k.volDiskFruId");
          if ($dfid && $DSK{$dfid}) {
            push(@pil, 
                  CIM::Instance->new('CIM_MediaPresent', [
                       [Antecedent => $DSK{$dfid}  ],  # the NWS_DiskDrive
                       [Dependent  => $vols[$k1]   ],
                       ]));
          }
       }
    }
  }

  return Ilist->new(\@pil);

}

# create instances of NWS_DiskDrive, CIM_Realizes, CIM_PhysicalPackage, 
# CIM_MediaPresent and CIM_StorageExtent, CIM_SoftwareElement, CIM_DeviceSoftware
#  $disk = NWS::T3->newDiskDrive($rep, "u1d1");

sub copyKey {
  my($class, $cd, $from, $to) = @_;
  $to->{"$cd.fruVendor"} =  $from->{"$cd.fruVendor"};
  $to->{"$cd.fruModel"} =  $from->{"$cd.fruModel"};
  $to->{"$cd.fruSerialNo"} =  $from->{"$cd.fruSerialNo"};
}

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

  return undef if (!exists $rep->{"$cd.fruVendor"});
  return "" if (! $rep->get("$cd.fruVendor") && !$rep->get("$cd.fruSerialNo"));

  my($k) = $rep->get("$cd.fruVendor") . "." .  $rep->get("$cd.fruModel") . ".";

  my($ser) = $rep->get("$cd.fruSerialNo");

  $k .= ($ser)? $ser : $cd;

  return $k;
}

sub getState {
  my($class, $rep, $cd) = @_;
  my($map) = PDM->getDeviceStateMap(lc($class->category()) . ".availability");
  my($state) = $map->get("fruStatus." . $rep->get("$cd.fruStatus") ) . 
               $map->get("fruState."  . $rep->get("$cd.fruState")  );
  return ($state eq "11")? 1:0;
}

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.fruStatus") . "-" . 
                $rep->get("$cd.fruState");


  $p1 = CIM::Instance->new('NWS_DiskDrive', [
                [SystemName 		=> $rep->get("$cd.fruVendor")." DiskDrive"],
                [DeviceID 	=> $serial_no],
                [Name     	=> $serial_no],
                [FruDiskRole        => $rep->get("$cd.fruDiskRole")],
                [FruDiskIsExpendable=> $rep->get("$cd.fruDiskIsExpendable")],
                [FruDiskIsRebuildable=> $rep->get("$cd.fruDiskIsRebuildable")],
                [FruDiskTemperature => $rep->get("$cd.fruDiskTemp")],
                [FruDiskCapacity    => $rep->get("$cd.fruDiskCapacity")],
                [FruErrors          => $rep->get("$cd.fruErrors")],
                [Port1State         => $rep->get("$cd.fruDiskPort1State")],
                [Port2State         => $rep->get("$cd.fruDiskPort2State")],
                [StatusInfo         => $status],
                [Status             => $class->getState($rep, $cd)],
                 ]);
  push(@il,$p1);

  $c1 = CIM::Instance->new('CIM_PhysicalPackage', [
                [Removable 	=> "Yes"],
                [Replaceable 	=> $rep->get("$cd.fruDiskIsExpendable")],
                [Tag 	        => $serial_no],
                [Name    	=> $serial_no],
                [SerialNumber 	=> $rep->get("$cd.fruSerialNo") ],
                [Manufacturer 	=> $rep->get("$cd.fruVendor")],  
                [Model 		=> $rep->get("$cd.fruModel")],  
                [Version 	=> $rep->get("$cd.fruRevision")],  
                    ]);

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

  return Ilist->new(\@il);

}

sub newMidplane {
  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.fruStatus") . "-" .
                $rep->get("$cd.fruState");


  $p1 = CIM::Instance->new('NWS_Midplane', [
                [SystemName             => $rep->get("$cd.fruVendor")." Midplane"],
                [DeviceID       => $serial_no],
                [Name           => $serial_no],
                [IsEnabled      => $rep->get("$cd.fruIsEnabled")],
                [IsSubstituted  => $rep->get("$cd.fruIsSubstituted")],
                [StatusInfo         => $status],
                [Status             => $class->getState($rep, $cd)],
                 ]);
  push(@il,$p1);

  $c1 = CIM::Instance->new('CIM_PhysicalPackage', [
                [Removable      => "Yes"],
                [Replaceable    => "No"],
                [Tag            => $serial_no],
                [Name           => $serial_no],
                [SerialNumber   => $rep->get("$cd.fruSerialNo") ],
                [Manufacturer   => $rep->get("$cd.fruVendor")],  
                [Model          => $rep->get("$cd.fruModel")],
                [Version        => $rep->get("$cd.fruRevision")],   
                    ]);

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

  push(@il,$a1);

  return Ilist->new(\@il);

}


# create instances of NWS_Controller, CIM_Realizes, CIM_Card, CIM_SoftwareElement and
#CIM_DeviceSoftware (Note: All attributes related to T3's software will be in the
#controller's CIM_SoftwareElement class.

sub newController {
  my($class, $rep, $cd, $index) = @_;
  my(@il, $p1, $c1, $a1);
  
  my($wwn) = $rep->get('id.wwn');

  my $serial_no = lc($rep->{"port.u${index}p1.portWWN"});

  return undef if (!$serial_no);
  my($port) = substr($cd,11,-3) . "p1";
  my($status) = $rep->get("${cd}.fruStatus") . "-" . 
                $rep->get("${cd}.fruState");
  my $ix = index($cd, ".");
  my $unit = substr($cd, $ix+1, 2);
  $wwn = $rep->{"port.$unit" . "p1.portWWN"};

  $p1 = CIM::Instance->new('NWS_Controller', [
                    [SystemName  =>  "Controller"],
                    [DeviceID     => $serial_no],
                    [Name         => $serial_no],
                    [FruErrors    => $rep->get("${cd}.fruErrors")],
                    [Role         => $rep->get("${cd}.fruCtlrRole")],
                    [PortErrors   => $rep->get("port.$port.portErrors")],
                    [PortStatus   => $rep->get("port.$port.portStatus")],
                    [PortSunHost  => $rep->get("port.$port.portSunHost")],
                    [PortType     => $rep->get("port.$port.portType")],
                    [StatusInfo   => $status],
                    [Status       => $class->getState($rep, $cd)],
                    ]);
  push(@il,$p1);

  $c1 = CIM::Instance->new('CIM_Card', [
                [Removable 			=> "Yes"],
                [Replaceable 		=> $rep->get("${cd}.fruCtlrIsExpendable")],
                [Tag 				=> $serial_no],
                [WWN 				=> $wwn      ],
                [Name  				=> $serial_no],
                [SerialNumber 		=> $rep->get("${cd}.fruSerialNo") ],
                [Manufacturer 		=> $rep->get("${cd}.fruVendor")],  
                [Model 				=> $rep->get("${cd}.fruModel")],  
                [Version 			=> $rep->get("${cd}.fruRevision")],  
                    ]);

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

  return Ilist->new(\@il);

}

# create instances of NWS_LoopCard, CIM_Realizes, CIM_Card
sub newLoopCard {
  my($class, $rep, $cd) = @_;
  my(@il, $a1, $c1, $p1);
  
  my($serial_no) = $class->getKey($rep, $cd);

  return undef if (!$serial_no);
  my($status) = $rep->get("${cd}.fruStatus") . "-" . 
                $rep->get("${cd}.fruState");
  $p1 = CIM::Instance->new('NWS_LoopCard', [
               [SystemName => $rep->get("${cd}.fruVendor")." LoopCard"],
               [DeviceID   => $serial_no ],
               [Name       => $serial_no ],
               [FruLoopCable1State=> $rep->get("${cd}.fruLoopCable1State")],
               [FruLoopCable2State=> $rep->get("${cd}.fruLoopCable2State")],
               [FruLoopMode       => $rep->get("${cd}.fruLoopMode")],
               [FruLoopTemp       => $rep->get("${cd}.fruLoopTemp")],
               [FruErrors         => $rep->get("${cd}.fruErrors")],
               [StatusInfo        => $status],
               [Status            => $class->getState($rep, $cd)],
                    ]);
  push(@il,$p1);

  $c1 = CIM::Instance->new('CIM_Card', [
               [Removable 			=> "Yes"],
               [Tag 				=> $serial_no],
               [Name 				=> $serial_no],
               [SerialNumber 		=> $rep->get("${cd}.fruSerialNo")],
               [Manufacturer 		=> $rep->get("${cd}.fruVendor")],  
               [Model 				=> $rep->get("${cd}.fruModel")],  
               [Version 			=> $rep->get("${cd}.fruRevision")],  
                    ]);
  push(@il, $c1);
  $a1 = CIM::Instance->new('CIM_Realizes', [
                [Antecedent 	=> $c1],
                [Dependent 		=> $p1],
                    ]);
  push(@il,$a1);

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

# create instances of NWS_PowerUnit, CIM_Realizes, CIM_PhysicalPackage,CIM_Container 

sub newPowerUnit {
  my($class, $rep, $cd) = @_;
  my(@il, $p1 ,$c1, $a1);
  
  my($status) = $rep->get("${cd}.fruStatus") . "-" . 
                $rep->get("${cd}.fruState");

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

  return undef if (!$serial_no);
  my($revision) = $rep->get("${cd}.fruRevision");
  if ($revision =~ /refer to/) {
    $revision = "";
  }
  $p1 = CIM::Instance->new('NWS_PowerUnit', [
               [SystemName   => $rep->get("${cd}.fruVendor")." PCU"],
               [DeviceID     => $serial_no],
               [Name         => $serial_no],
               [FruBatLife   => $rep->get("${cd}.fruPowerBatLife")],
               [FruErrors    => $rep->get("${cd}.fruErrors")],
               [Fan1State    => $rep->get("${cd}.fruPowerFan1State")],
               [Fan2State    => $rep->get("${cd}.fruPowerFan2State")],
               [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}.fruSerialNo") ],
               [Manufacturer 	=> $rep->get("${cd}.fruVendor")],  
               [Model 			=> $rep->get("${cd}.fruModel")],  
               [Version 		=> $revision],
                    ]);

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

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

1;
