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

#  $Name: bld21_017 $ 
#  $Id: Internal.pm,v 1.4 2005/04/20 17:23:32 sbrooks Exp $


use base 'Health';
use NWS::Internal;
use Ilist;
use Message;
use Catalog;
use Report;
use Events;
use strict;
use Debug;
use Agent::V880DISK;
sub revision {'$Revision: 1.4 $'}


sub all_logic {
  my($hm, $report) = @_;
  my($ev, $ed, $pertains, $x ,$y, $contain, $sd);
  my($orep, $comp);
  $DB::single = 1;
  my($rep)     = $report->content;
  my($oreport) = PDM->getOldReport($report->fileKey);
  my $wwn      = $rep->{'id.wwn'};
  my $type     = $report->id('category');
  my($id)      = $report->id("display");
  my($log)     = $report->log();
  CIM->version("1.1");
  if (!$wwn) {
     Debug->err(ERROR => "This $type ($wwn) cannot be identified");
     return;
  }

  return if ( $hm->connectionEvent($wwn, $report, {method => 1, threshold_severity => 0} )); # return if cannot_connect

  my $freq  = System->get_renv()->{audit_freq} || 7;
  my $audit = System->get_audit() ? "YES" : Timer->isXdays("Audit$wwn", $freq);
  if (!$oreport || $audit eq "YES" ) {  # new t300 or audit time.

     my($etype) = $audit eq "YES" ? "$type.AuditEvent" : "$type.DiscoveryEvent";
     my($title) = $audit eq "YES" ? "Auditing an ":"Discovered a new ";
     my($dt)    = "A" if (!$audit);

     Grid->setCode($etype);
     $ev = CIM::Instance->new('NWS_Event', [
                  [ EventType   => $etype ],
                  [ Target      => "$type:$wwn"   ],
                  [ TargetName  => $id    ],
                  [ EventId     => PDM->getEventSequence  ],
                  [ Description => "$title $type called $id"],
                  [ Data        => $hm->serial($rep) ],
                         ]);

     $sd = Events->sourceDetector({ event => $ev , host => 1, rep => $rep});
      
     my($p) = NWS::Internal->newSystem($rep);

     $pertains = CIM::Instance->new('NWS_EventPertainsToSystem', [
                  [ Event       => $ev  ],
                  [ Element     => $p->[0] ],
                  [ DiscoveryType => $dt],
                    ]);

     my($monitors) = CIM::Instance->new('NWS_AgentMonitors', [
                  [ Agent       => $sd->[0]  ],
                  [ Element     => $p->[0] ],
                    ]);

     $ed = Message->new( { id        => $report->id,
                            instances => [$ev, @$sd, @$p, $monitors, $pertains ],
                            severity  => Message::SEVERITY_NORMAL });

     PDM->saveMessage($ed);


  }
  $orep = ($oreport)? $oreport->content() : $rep; # same report if new disco.

  $hm->locationChangeEvent($report, $rep, $orep, $wwn);
  my($physicalFrame) = CIM::Key->new( ['CIM_PhysicalFrame', # frame key 
                       Tag               => $wwn,
                       CreationClassName => 'CIM_PhysicalFrame' ]);

  my($j);
  my $max = $rep->get("info.count");

  for ($j=0; $j < $max; $j++) {
      my($comp) = "disk.$j";
      my($oserial) = Util->rtrim($orep->get("$comp.NodeWWN")) ;
      my($nserial) = Util->rtrim($rep->get("$comp.NodeWWN")) ;
      if ($oserial eq $nserial) {
         Grid->setCode("$type.StateChangeEvent.disk");
         $hm->stateChangeEvent($comp, 'status', $report, $rep, $orep, 'CIM_PhysicalPackage', $nserial, $wwn);
      } else {
         if ($oserial) {
           Grid->setCode("$type.ComponentRemoveEvent.disk");
           $hm->removeCompEvent($comp,$physicalFrame, $report, $orep, 'CIM_PhysicalPackage',$oserial, $wwn);
         }
         if ($nserial) {
           my($disk) = NWS::Internal->newDiskDrive($rep, $comp);
           Grid->setCode("$type.ComponentInsertEvent.disk");
           $hm->insertCompEvent($comp,$physicalFrame, $report,  $orep, $disk, $nserial, $wwn);
         }
      }
  }

}


sub status {
   my($hm, $rep, $orep, $comp) = @_;
   my($map) = PDM->getDeviceStateMap("internal.availability");
   my($state, $ostate, $status, $ostatus, $old, $new, $sev, $act);

   $status   = $rep->getState("$comp.Status");
   $ostatus = $orep->getState("$comp.Status");

   ($old, $new, $sev, $act) = $map->transition("disk.status.$ostatus", 
                                      "disk.status.$status", $orep, $rep);

   return ($ostatus, $status, $old, $new, $sev, $act);
}

1;
