package Client::Inventory;
#
# snapshot: probe device take a snapshot
# compare:  probe device and compare to last snapshot
#

use strict;
use Agent;
use Client;
use DeviceReport;
use Health;
use System;

#
# Usage:
#    ?GO=Client::Inventory::probe    
#              Take a snapshot and save it for future comparison
#    return: <INVENTORY>shapshot</INVENTORY>

#    ?GO=Client::Inventory::compare
#              Take another snapshot qand compare it to the last probe()
#    return sample:
#    <INVENTORY>
#      <INFO>
#         <NAME>diag-lsi1.Central.Sun.COM</NAME>
#         <KEY>SUN.348-0046776.0412071149</KEY>
#         <IP>172.20.35.110</IP>
#      </INFO>
#          <DELETE>
#            <ID>disk.10</ID>
#            <FULL_TOPIC>Drive.11.6</FULL_TOPIC>
#            <SERIAL>SEAGATE.ST336753FC.3HX1ZM10000074293X9X</SERIAL>
#          </DELETE>
#          <INSERT>
#            <ID>disk.10</ID>
#            <FULL_TOPIC>Drive.11.6</FULL_TOPIC>
#            <SERIAL>XXSEAGATE.ST336753FC.3HX1ZM10000074293X9X</SERIAL>
#          </INSERT>
#          <UPDATE>
#            <ID>disk.11</ID>
#            <COMPONENT>Drive.11.5</COMPONENT>
#            <SERIAL>SEAGATE.ST336753FC.3HX1ZL38000074293D26</SERIAL>
#            <OLD_AVAILABILITY>Running/Full Power</OLD_AVAILABILITY>
#            <AVAILABILITY>XRunning/Full Power</AVAILABILITY>
#            <OLD_REVISION>MS04</OLD_REVISION>
#            <REVISION>MS04</REVISION>
#          </UPDATE>
#  


sub probe {
  my($key) = @_;
  my($device);
  
  my $pos = index($key, ":");
  my $device_type = substr($key, 0, $pos);
  my $key0 = substr($key, $pos + 1);

#  my($device_type, $key0) = split(/\:/, $key);

  my $DIR = System->get_home() . "/DATA/Inventory";
  mkdir $DIR, 0777 if (!-d $DIR);

  my ($renv, $devs) = PDM::ConfigFile->read();
  foreach my $d (@$devs) {
    if ($d->{key} eq $key0) {
      $device = $d; last;
    }
  }
  if (!$device) {
     return ("Device not found ($key0)");
  }

  my $agent = new Agent($device_type);
  my $rep   = $agent->INSTRUMENTATION($device);
  return (undef, $rep, $device);
}



# PROBE DEVICE REAL-TIME
# SAVE REPORT IN TEMPORARY LOCATIOn
# RETURN xmlFruList() for this TEMP REPORT.

# url=rashttp?GO=Client::Inventory::fruList&key=6130:SUN.348-0046776.0412071149
# filter=disk

sub fruList {
  my($q) = @_;
  my $key    = $q->{key};
  my $filter = $q->{filter};

  my($device_type, $key0) = split(/\:/, $key);

  my($err, $rep, $dev) = &probe($key);

  if ($err) {
     print Client->error("xml", 101, "Error reading report $key: $err");
     return;
  }
  print Client->http_OK();

  my $devReport = new DeviceReport($device_type);

  my $id = { deviceName => $dev->{key}, name => $dev->{name}, category => $dev->{type},
             display => $dev->{name} };
  my $report= Report->new($id, $rep);

  my($S, $out) = $devReport->xmlFruList($report, $q);
  print $out;

}




# - Take a snapshot of device in Inventory/key

sub snapshot {
  my($q) = @_;
  
  my($err, $rep) = &probe($q->{key});

  if ($err) {
     print Client->error("xml", 202, $err);
     return;
  }

  print Client->http_OK();
  Util->serialize("Inventory/$q->{key}", $rep);

  print "<INVENTORY>shapshot</INVENTORY>\n";
}


#  - Take a snapshot in Inventory/key.new
#  - Compare key with key.new

sub compare {
  my($q) = @_;

  my($err, $rep, $device) = &probe($q->{key});

  if ($err) {
     print Client->error("xml", 202, $err);
     return;
  }

  Util->serialize("Inventory/$q->{key}.new", $rep);
  my $orep = Util->deserialize("Inventory/$q->{key}");

  print Client->http_OK();

  print <<EOF;
  <INVENTORY>
    <INFO>
       <NAME>$device->{name}</NAME>
       <KEY>$device->{key}</KEY>
       <IP>$device->{ipno}</IP>
    </INFO>
EOF


  my($device_type, $key0) = split(/\:/, $q->{key});

  my $health = new Health($device_type);
  my $lists = $health->component_lists();

  foreach my $label (keys %$lists) {
      next if ($label ne "physical");
      my $val = $lists->{$label};
      my $report_names = $val->[0];
      my $tag_name     = $val->[1];

      my($INSERTS, $DELETES, $UPDATES) = Health->idu_map($rep, $orep, $report_names, $tag_name);


      foreach my $el (keys %$DELETES) {
        my $comp = $DELETES->{$el};                       
        my $topic = $orep->{"$comp._ElementName"};
        print <<EOF;
        <DELETE>
          <ID>$comp</ID>
          <FULL_TOPIC>$topic</FULL_TOPIC>
          <SERIAL>$el</SERIAL>
        </DELETE>
EOF
      }

      foreach my $el (keys %$INSERTS) { 
        my $comp = $INSERTS->{$el}; 
        my $topic = $rep->{"$comp._ElementName"};
        print <<EOF;
        <INSERT>
          <ID>$comp</ID>
          <FULL_TOPIC>$topic</FULL_TOPIC>
          <SERIAL>$el</SERIAL>
        </INSERT>
EOF

      }

      my $FRU  = COMMON->fruMap($rep);
      my $OFRU = COMMON->fruMap($orep);

      foreach my $comp (keys %$UPDATES) {
         my $name   =  $rep->{"$comp._ElementName"};
         my $avail  =  $rep->{"$comp._Availability"};
         my $oavail = $orep->{"$comp._Availability"};

         my $realiz =  $rep->{"$comp._Realized"};
         my $rev    =  $FRU->{$realiz}{fwRev};
         my $orev   = $OFRU->{$realiz}{fwRev};

         if ( ($avail && $avail ne $oavail) || ($rev ne $orev)
               ) {
            print <<EOF;
        <UPDATE>
          <ID>$comp</ID>
          <COMPONENT>$name</COMPONENT>
          <SERIAL>$realiz</SERIAL>
          <OLD_AVAILABILITY>$oavail</OLD_AVAILABILITY>
          <AVAILABILITY>$avail</AVAILABILITY>
          <OLD_REVISION>$orev</OLD_REVISION>
          <REVISION>$rev</REVISION>
        </UPDATE>
EOF
         }
      }
  }

  print "</INVENTORY>\n";

}

sub fruSummary {
  my($q) = @_;
  my $key    = $q->{key};

  my($device_type, $key0) = split(/\:/, $key);

  my($err, $rep, $dev) = &probe($key);

  if ($err) {
     print Client->error("xml", 101, "Error reading report $key: $err");
     return;
  }
  print Client->http_OK();

  my $devReport = new DeviceReport($device_type);

  my $id = { deviceName => $dev->{key}, name => $dev->{name}, category => $dev->{type},
             display => $dev->{name} };
  my $report= Report->new($id, $rep);
  my($S, $out) = $devReport->xmlSummary($report, $q);
  print $out;
}


1;
