package Agent::HBASTORAGE;
use System;
use strict;
use Agent;
use base 'Agent';
use Util;
use System;
use Discover;
use TO;

#------------------------------------------
# monitors the paths and inband devices
# found with the hba-api
#------------------------------------------

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

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

  bless ($self, 'Agent::HBASTORAGE');
  return $self;
}
use vars qw($ERR );
#
# Used to generate a hbaapi report and
# optionally fix the topology with the informatio found.
#

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

  my($renv) = System->get_renv();
  return [] if ($renv->{solution} ne "N");

  $DB::single = 1;
  my $processed_list = [];

  my $auto_topo = !$renv->{manual_topology};

  my $freq  = $renv->{'hbaapi.freq' } || 60*12;
  my $delay = $renv->{"hbaapi.delay"} || 5;
  my $type  =  Report::CAT_HBASTORAGE;

  if (Timer->isXmins("hbaapi_storage", $freq) || System->get_allDevices()) {
    Debug->print1("Executing HBA Storage");

    my($hba_list, $switch_list) =  HBAApi->run();
    my $wwn = "hbas-" . System->hostid();

    my $dev = { type => $type, key => $wwn };

    if ($auto_topo) {
       Discover->updateTopoHost($hba_list);
    }
    my($report) = $agent->INSTRUMENTATION($hba_list, 
                              { type => $type, key => $wwn, name => "$type $wwn" } );

    my $problems = PDM->get_last_event();

    my($id) = {
                deviceName=> $wwn,
                active    => "Y",
                class     => "host.$type",
                name      => uc($type) . " " . $renv->{hostname},
                display   => uc($type) . " " . $renv->{hostname},
                category  => $type,
                ip        => Util->name2ip(),
               };

     my $new_rep = Report->new($id, $report);

     require Health::HBAStorage;
     Health::HBAStorage->all_logic($new_rep);
     PDM->saveReport($new_rep);

     my ($broke, $abort) = $agent->new_events($problems, $dev, 1);
     push(@$processed_list, $dev);
     last if ($broke && $pass == 1 || $abort);
  }
  return $processed_list;
}

sub INSTRUMENTATION {
    my($agent, $hba_list, $device) = @_;
    my (%R);
    my( $x, $p, @device_reports);
    my $dev_cnt =0;
    return Report->readTest($device) if (System->get_testMode());

    for ($x=0; $x <= $#$hba_list; $x++) {
       my $hba = $hba_list->[$x];

       #foreach my $el (keys %$hba) {
       #  next if ($el eq "deviceInfo");
       #  $R{"hba.$x.info.$el"} = $hba->{$el};
       #}

       my $devices = $hba->{deviceInfo};
       my %LIST;
       for ($p=0; $p <= $#$devices; $p++) {
          my $device= $devices->[$p];
          my $key = TO::Node->knownDevice($device) ? 
                            "IB" . ($device->{ENCNodeWWN} ||  $device->{NodeWWN} ) 
                         :  "H$hba->{NodeWWN}";
          push(@{$LIST{$key}}, $device);
          #foreach my $el (keys %$device) {
          #  $R{"hba.$x.device.$p.$el"} = $device->{$el};
          #}
       }
       foreach my $wwn (keys %LIST) {
          my $ports = $LIST{$wwn};
          $agent->deviceReport(\%R, $dev_cnt, $ports, $wwn, $hba);
          $dev_cnt++;
       }
    }

    return \%R;
}

# CREATE A DEVICE specific report for OLD_REPORTS and the GUI
# ADD TO THE OVERALL device report for the health module.

sub deviceReport {
  my($agent, $R, $dev_cnt, $ports, $wwn, $hba) = @_;

  my $type =  Report::CAT_HBASTORAGE;
  my $key  = $wwn;
  my ($name, $x);
  for ($x=0; $x <= $#$ports; $x++)  {
        if ($ports->[$x]{BoxName} ) {
           $name = $ports->[$x]{BoxName};
           last;
        }
  }
  $name = $wwn if (!$name);

  my $p0 = $ports->[0];
  my $renv = System->get_renv();
  

  my $id = { deviceName => $key,
             active    => "Y",
             class     => "storage.$type",
             name      => $name,
             display   => "$p0->{Vendor} $name",
             category  => $type,
           };
  my ($p, %R2);
  $R2{"id.key"} = $key;
  $R->{"device.$dev_cnt.id.key"} = $key;
  my ($wwn_cnt, $wwn_list, $userLabel);

  for ($p=0; $p <= $#$ports; $p++) {
    my $port = $ports->[$p];
    if (substr($wwn,0,1) ne "H" || $wwn_cnt++ < 10) {
      $wwn_list .= "$port->{PortWWN},";
    }
    foreach my $e (keys %$port) {
      $R2{"fcport.$p.$e"} = $port->{$e};
      $R->{"device.$dev_cnt.fcport.$p.$e"} = $port->{$e};
    }
    $R2{"fcport.$p._Vendor"} = $R2{"fcport.$p.Vendor"};
    $R2{"fcport.$p._Product"}= $R2{"fcport.$p.ProductID"};
    if (!$userLabel && $R2{"fcport.$p.Vendor"} ){
      $userLabel = $R2{"fcport.$p.Vendor"} . "-" . $R2{"fcport.$p.ProductID"};
    }
    $R2{"fcport.$p._Revision"}  = $R2{"fcport.$p.Model"};
    $R2{"fcport.$p._Caption"}= $R2{"fcport.$p.Vendor"} . "-" . $R2{"fcport.$p.ProductID"};
    $R2{"fcport.$p._Status"} = "N/A";

    $R2{"fcport.$p._WWN"}    = $R2{"fcport.$p.PortWWN"};
    $R2{"fcport.$p._Name"}   = $R2{"fcport.$p.PortWWN"};
    $R2{"fcport.$p._ElementName"}   = $R2{"fcport.$p.PortWWN"};

    $R->{"device.$dev_cnt.fcport.$p._Vendor"} = $R2{"fcport.$p.Vendor"};
    $R->{"device.$dev_cnt.fcport.$p._Product"}= $R2{"fcport.$p.ProductID"};
    $R->{"device.$dev_cnt.fcport.$p._Revision"}  = $R2{"fcport.$p.Model"};
    $R->{"device.$dev_cnt.fcport.$p._Caption"}= $R2{"fcport.$p.Vendor"} . "-" . $R2{"fcport.$p.ProductID"};
    $R->{"device.$dev_cnt.fcport.$p._Status"} = "N/A";

    $R->{"device.$dev_cnt.fcport.$p._WWN"}    = $R2{"fcport.$p.PortWWN"};
    $R->{"device.$dev_cnt.fcport.$p._Name"}   = $R2{"fcport.$p.PortWWN"};
    $R->{"device.$dev_cnt.fcport.$p._ElementName"}   = $R2{"fcport.$p.PortWWN"};
  }
  $R2{"fcport.count"} = $#$ports + 1;
  $R->{"device.$dev_cnt.fcport.count"} = $#$ports + 1;

  foreach my $el (keys %$hba) {
     next if ($el eq "deviceInfo");
     $R2{"hba.$el"} = $hba->{$el};
     $R->{"device.$dev_cnt.hba.$el"} = $hba->{$el};
  }

  $R2{"hba.host"}                  = $renv->{hostname};
  $R->{"device.$dev_cnt.hba.host"} = $renv->{hostname};

  chop($wwn_list) if ($wwn_list);

  $R2{"info.remote_list_info"} = 
   "{port_wwns=>'$wwn_list', userLabel => \"InBand $userLabel\"}";

  my $report = Report->new($id, \%R2);
 # PDM->saveReport($report);

}



1;

