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

#  $Name:  $ 
#  $Id: NTC.pm,v 1.10 2006/07/20 16:25:22 mckenney Exp $

 
use Health;
use PDM;
use Carp;
use Data::Dumper;
use Report;
use strict;
use CIM::Instance;
use Message;
use Debug;
use TO;
use Health::Server;
use NWS::NTC;
  
use Health::Server;
use base 'Health::Server';

sub revision {'$Revision: 1.10 $'}
 

sub all_logic {
  my($hm, $report) = @_;
  my($run, $orep, $x);
  my($renv)    = System->get_renv();
  my $Config   = PDM::ConfigFile->read();

  CIM->version("1.1");
  $DB::single = 1;

  my $rep     = $report->content();
  my $oreport = PDM->getOldReport($report->fileKey);
  my $orep    = $oreport->content()  if ($oreport);
  my $id      = $report->deviceName();
  my $key = $renv->{cust_no} || System->hostid();
  my $nkey = System->hostid();
  my $wwn      = $report->id('deviceName');
  my $ip      = $report->id('ip');
  my ($ev, $mgmtLevel, $ed, $pertains, $sd);

  my $freq  = $renv->{audit_freq} || 7;
  my $audit = System->get_audit() ? "YES" : Timer->isXdays("Audit$wwn", $freq);

  if (!$oreport || $audit eq "YES" ) {  
     # new NTC or audit time.
     my($etype) = $audit eq "YES" ? "ntc.AuditEvent" : "ntc.DiscoveryEvent";
     my($title) = $audit eq "YES" ? "Auditing":"Discovering";
     my($dt)    = "A" if (!$audit);
     Grid->setCode($etype);
     $ev = CIM::Instance->new('NWS_Event', [
                  [ EventType   => $etype  ],
                  [ Target      => "ntc:$wwn"    ],
                  [ TargetName  => $id     ],
                  [ MgmtLevel   => $mgmtLevel],
                  [ SourceIP    => $ip     ],
                  [ EventId     => PDM->getEventSequence  ],
                  [ Description => "$title  $id"],
                         ]);
 
     $sd = Events->sourceDetector({ event => $ev , host => 1, rep => $rep});
      
     my($p) = NWS::NTC->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);
  }

  if (!$oreport){
    return;
  }

  if (exists ($rep->{"info.ping"})){
     my $IP = $rep->{"info.ip"};
     my $STATUS = $rep->{"info.ping"};

     my $eventSent = $hm->ntcCommLostEvent($report, "ntc", $IP, $STATUS, "TerminalConcentrator", $key);

     if($eventSent){
       # Don't do any more alerts
       return;
     }
  }

  # Check power supplies
  foreach my $ps ('A','B') {

     my $ps_status     = $rep->{"power.${ps}.status"};
     my $ops_status    = $orep->{"power.${ps}.status"};
     if ($ps_status ne $ops_status) {
        my $sev = $ps_status eq "up" ? 0:2;
        if($sev){
	   Grid->setCode("ntc.AlarmEvent.power_down");
        }else{
           Grid->setCode("ntc.AlarmEvent.power_okay");
        }

       $hm->alarmEvent("NTC power $ps", "", $report, $wwn,
        "Power input on power $ps changed from '$ops_status' to '$ps_status' ",
        $sev, "NTC power $ps",
           { mgmtLevel => "D" } );

     }
  }

  # Check pc cards (Modem)
  for (my $x = 1; $x <=$rep->{"pccard_slotmax"}; $x++){
     if(!exists($orep->{"pccard.${x}.CardType"})){
        next;
     }

     # Check card type
     my $cardType  = $rep->{"pccard.${x}.CardType"};
     my $ocardType = $orep->{"pccard.${x}.CardType"};
     
     if ($cardType ne $ocardType) {
        my $sev = $ocardType eq "none" ? 0:2;
        if($sev){
	   Grid->setCode("ntc.AlarmEvent.slot_empty");
        }else{
           Grid->setCode("ntc.AlarmEvent.slot_occupied");
        }

       $hm->alarmEvent("NTC PCCard slot $x", "", $report, $wwn,
        "PC Card $x type changed from '$ocardType' to '$cardType' ",
        $sev, "NTC PC Card $x",
           { mgmtLevel => "D" } );

     }

     # Check Modem State
     my $modem  = $rep->{"pccard.${x}.ModemState"};
     my $omodem = $orep->{"pccard.${x}.ModemState"};
     
     if ($modem ne $omodem) {
        my $sev = 0;
        Grid->setCode("ntc.AlarmEvent.modemChanged");

        $hm->alarmEvent("NTC PCCard slot $x", "", $report, $wwn,
         "PC Card $x modem state changed from '$omodem' to '$modem' ",
        $sev, "NTC PC Card $x",
           { mgmtLevel => "D" } );

     }


  }



}

sub ntcCommLostEvent {
  my($hm, $report, $code, $IP, $STATUS, $name, $id) = @_;

  my($tran, $reps, $in_a_row_counter)= Transition->getTransition( {
                                          key => $IP,
                                         code => $code,
                                        value => $STATUS,
                             transition_value => "CannotPing",
                                       repeat => '24h'
                                        } );

  if ($tran =~ /IN/  || $tran =~ /OUT/ || $tran =~ /LOST/) {
        my ($et, $desc, $sev);
        if ($tran =~ /IN/ || $tran =~ /LOST/) {
          $et   = "ntc.CommunicationLostEvent";
          Grid->setCode("sp.CommunicationLostEvent.$code");
	  # Need 2 in a row to be down.
          if($in_a_row_counter < 1){
            $sev  = Message::SEVERITY_NORMAL;
          }else{
            $sev  = Message::SEVERITY_WARNING;
          }
          $desc = "Lost Communication(oob) with $name / $IP";
        } else {
          $et   = "ntc.CommunicationEstablishedEvent";
          Grid->setCode("ntc.CommunicationEstablishedEvent.$code");
          $sev  = Message::SEVERITY_NORMAL;
          $desc = "Regained Communication(oob) with $name / $IP";
        }
        my $ev = CIM::Instance->new('NWS_CommunicationLostEvent', [
                  [ EventType       => $et  ],
                  [ EventId         => PDM->getEventSequence  ],
                  [ Severity        => $sev ],
                  [ Actionable      => ($sev > 0) ],
                  [ Component       => "ntc.$code"],
                  [ Target          => $report->fileKey() ],
                  [ Caption         => $code ],
                  [ Description     => $desc ]
                   ]);
        my $sd = Events->sourceDetector({ event => $ev });

        my $key = CIM::Key->new( ['NWS_System',
                   'Name'       =>  $id,
              CreationClassName => 'NWS_System']);

        my $pertains = CIM::Instance->new('NWS_EventPertainsToSystem', [
                  [ Event       => $ev  ],
                  [ Element     => $key ],
                    ]);

        my $ed = Message->new( { id   => {},
                            instances => [$ev, @$sd, $pertains ], 
                            severity  => $sev });

        PDM->saveMessage($ed);
	return 1;
  }
  return 0;
}

1;
