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

#  $Name: bld61_002 $
#  $Id:
use strict;
use Agent;
use base 'Agent';
use Health::SAN;
use Debug;
use Grid;
use Snapshot;

sub isSelectable {0}
sub revision {'$Revision: 1.8 $'}


sub new {
  my($self) = Agent->new();

  bless ($self, 'Agent::SLAVE');
  return $self;
}

# $pass = 0 (INSPECTOR)

sub RUN {
  my($agent, $static_list, $pass ) = @_;

  return [] if (Util->findMaster());
  my $Config = System->get_Config();

  my( $x, $h);
  my($l, $s, $rc, $url, $ed);
  my $renv = System->get_renv();
 
#
# POLL ALL SLAVES, GENERATE CommLost Events
# GET EVENTS from slaves and store in PDM.
#
  CIM->version("1.1");
  $DB::single = 1;
  my $hosts = System->get_configHosts();
  my @processed_list;

  foreach $h ($agent->deviceList($static_list, "host")) {
     if ($h->{dh} eq "Y") {
        Debug->print2(" -> skipping $h->{name}, datahost only");
        next;
     }   
     if ($h->{active_agent} eq "N") {
        Debug->print2(" -> skipping $h->{name}, slave not active");
        next;
     }
     next if (!$h->{ip});
  
     my $Events = System->get_home() . "/DATA/Events/$h->{name}.push";
     my $Push   = -f $Events;
    
     # CALL SLAVE WHEN THERE ARE AVENTS OR EVERY  HOUR
     my $probe_freq = $renv->{'slave.probe_freq'} || 60;
 
     if (Timer->isXmins("SL.$h->{name}", $probe_freq) || $Push) { 
        
        push(@processed_list, $h);

        if ($Push) {
          Debug->print1("-> SLAVE $h->{name}: Pulling events");
          unlink $Events;
        } else {
          Debug->print1("-> SLAVE $h->{name}: GET-INFO and Pulling events");
          my $info = Util->rasInfo($h->{ip});
          my $alive = $info->{hostid} ? "Y" : "N";
          my $tran = &commEvent($alive, $h);
          next if ($tran =~ /IN/ || $tran eq "LOST");
        }
        my $ipno = $h->{ipno} || $h->{ip};
        $rc = Agent::SLAVE->readSlaveData($ipno, "SLAVE_DATA.2", $h->{name}, 20);
        $rc = Agent::SLAVE->readSlaveData($ipno, "SLAVE_DATA", $h->{name}, 20);
      }
  }
  return \@processed_list;

}

sub commEvent {
  my($alive, $h) = @_;

     my $ip   = $h->{ip};
     my $ipno = $h->{ipno} || $h->{ip};

     my $tran  = Transition->getTransition( {   key => $ip,
                                           code => 'alive',
                                          value => $alive,
                               transition_value => "N",
                                         repeat => '8h',
                                   });
     if ($tran =~ /IN/  || $tran =~ /OUT/) {
            my($et, $desc, $sev, $nws, $avail);
            if ($tran =~ /IN/) {
              $h->{problems} = 1;
              $et   = 'agent.CommunicationLostEvent';
              $desc = "Lost Communication with $h->{name} at $ipno";
              $nws  = 'NWS_CommunicationLostEvent';
              $sev  =  Message::SEVERITY_DOWN;
              $avail= 0;
              Grid->setCode("agent.CommunicationLostEvent.oob");
  
            } else {
              $et   = 'agent.CommunicationEstablishedEvent';
              $nws  = 'NWS_CommunicationEstablishedEvent';
              $desc = "Regained communication with $h->{name} at $ipno regained";
              $sev  =  Message::SEVERITY_NORMAL;
              $avail= 1;
              Grid->setCode("agent.CommunicationEstablishedEvent.oob");
            }
  
         my $ev = CIM::Instance->new($nws, [
                    [ EventType       => $et  ],
                    [ EventId         => PDM->getEventSequence  ],
                    [ Severity        => $sev ],
                    [ Actionable      => ($sev > 0) ],
                    [ Target          => "host:$h->{name}" ],
                    [ TargetName      => $h->{name} ],
                    [ Caption         => 'oob' ],
                    [ Description     => $desc ]
                     ]);
  
         State->saveState('host',  $h->{name}, "", 
                              Util->shortHostname($h->{name}), $sev, $desc,$avail , $ev);
  
         my $sd = Events->sourceDetector({ event => $ev });
         my $pertains = CIM::Instance->new('NWS_EventPertainsToSoftwareElement', [
                    [ Event      => $ev  ],
                    [ Element    => $sd->[0] ],
                      ]);
         my $ed = Message->new( { id   => {},
                             instances => [$ev, @$sd, $pertains ], severity  => $sev });
         PDM->saveMessage($ed);
     }
     return $tran;
}

sub readSlaveData {
  my($agent, $ipno, $file, $host, $to) = @_;

  my($x, $s, $rc, $l);
  $to = 20 if (!$to);
  if (System->get_testMode()) {
     open(OO, System->get_home() . "/DATA/$file.$ipno");
     while ($l = <OO>) {
        $rc .= $l;
     }
     close(OO);
  } else {
     $rc  = Util::Http->readFileDelete($ipno, $file, $to);
     Snapshot->appendFile("$file.$ipno", $rc, {nocomment => 1});
  }
  my @LIST;
  
  if (length($rc) > 2) {
     my(@l) = split(/\n/, $rc); 
     next if ($#l < 0);
     $s = "";
     Debug->print2("Receiving $#l lines from $host");
     for ($x = 0; $x <= $#l; $x++) {
         if (substr($l[$x],0,2) eq "-E") {
            eval {
                my $ed = Message->fromC($s);
                if ($ed) {
                  my $mess_seq = $agent->process($ed, $host);
                  push(@LIST, $mess_seq) if ($mess_seq);
                }
            };
            Debug->err(HTTP_ERROR => "failed to transfer from slave $@") if ($@);
            $s = "";
         } else {
           $s .= $l[$x] . "\n";
         }
     }
  }
  return \@LIST;
}

use CIM;
use FCRules;

sub process {
  my($agent, $ed, $hostname) = @_;

  CIM->version("1.1");
  my $date = FCRules->today();

  my $found = 0;
  my $ev = $ed->instances(0);
  $ev->setValue("MasterHostid", System->hostid()) if ($ev);
  my $type = $ev->value("EventType");

  if ($type eq "san.fcEvent") {
     my $data = $ev->value("Data");
     my ($VAR1);
     eval $data;
     Health::SAN->processFC($VAR1) if ($VAR1);
     return undef;

  } else {
     return PDM->saveMessage($ed, $hostname);
  }
}



1;
