package Client::Upgrade;
use Inventory;
use PPRO;
use strict;
use Client;
use Process;

#
# Clear Patch Upgrade Report
#
sub clearReport {
  print Client->http_OK();
  my $D = System->get_home() . "/DATA/tmp";
  unlink "$D/Upgrade";
  unlink "$D/Upgrade_pid";
  unlink "$D/Patchlist";
  unlink "$D/Patchlist_pid";
  return "OK";
}

#
# Generate Patch Upgrade Report
#
sub generateReport {
  print Client->http_OK();
  my $SID = "storade";
  my $command = System->get_home() . "/bin/ras_patchlist -S $SID -b";
  system($command);
  sleep(1);
  return "OK";
}

#
# Apply Patches
#
sub applyPatches {
  my($q) = @_;

  print Client->http_OK();

  my $cli  = PPRO->cli_path();
  my $renv = System->get_renv();

  my $info;
  my $list;
  my $SID  = "storade";
  my $rep  = Process->read(undef, "Patchlist");
  my $ppro = PPRO->parse($rep->{data}{report});

  my (%DEV, $err);
  foreach my $el (keys %$q) {
    if (substr($el,0,4) eq "sel_") {
      my $k = substr($el,4);
      $list .= "$k:";
      $DEV{substr($el,4)} = 1;
    }
  }
  foreach my $el (keys %$q) {
    if (substr($el,0,6) eq "patch_") {
      my($ip0, $patch0) = split(/\#/, substr($el,6));
      if (!$DEV{$ip0}) {
        $list .= substr($el,6) . ":";
      } else {
        $err .= "error";
      }
    }
  }
  chop($list) if ($list);
  if (!$list) {
    $info .= "select one";
  } else {
    my $command =  System->get_home() . "/bin/ras_upgrade -m S -S $SID -i \"$list\" -b";
    system($command);
    sleep(1);
    $info .= "task started: $command";
  }
  print $info;
}

#
# List Patches
#
sub listPatches {
  my($q) = @_;
 
  print Client->http_OK();

  my $Config = PDM::ConfigFile->read();

  my $rep  = Process->read(undef, "Patchlist");
  my $ppro = PPRO->parse($rep->{data}{report});

  if ($ppro->{ERRORS}) {
    print "<ERROR>error</ERROR>\n";
    return;
  }

  my $inv = Inventory->readInventory();
  my %IP; # map devives by ipno
  foreach my $d (@{$inv->getDevices()}) {
    $IP{$d->{ipno}} = $d;
  }

  my $State = State->getComponentState(0);

  print "<PATCH_UPGRADE_REPORT>\n";
  print "  <DATE>$rep->{date}</DATE>\n";
  foreach my $pp (@{$ppro->devices()}) {
    my $inv_d = $IP{$pp->key()};
    my $ip    = $pp->key();
    my $name  = $inv_d->{name};
    my $dev   = $Config->deviceByIP($ip);

    print "  <DEVICE>\n";
    print "    <NAME>$name</NAME>\n";
    print "    <IP>$ip</IP>\n";
    print "    <KEY>$dev->{key}</KEY>\n";
    print "    <TYPE>$dev->{type}</TYPE>\n";

    my $P = $pp->patches();

    my ($k, $sev);
    my $type = lc($pp->type());
    if ($type eq "sunos") {
      $k = "sp:" . System->hostid();
    } elsif ($dev) {
      $k = "$dev->{type}:$dev->{key}"
    } 
    $sev = 0;
    if (exists $State->{$k}) {
      $sev = int($State->{$k}[0] + 0.5);
    }
    print "    <ALARM_SEVERITY>$sev</ALARM_SEVERITY>\n";

    foreach my $patch (@$P) {
      my $pid = $patch->{patchID};
      my $syn = $patch->{synopsis};
      my $err = $pp->error($patch->{error});
      my $frus;
      print "    <PATCHID>$pid</PATCHID>\n";
      print "    <PATCH_SYNOPSIS>$syn</PATCH_SYNOPSIS>\n";
      foreach my $fru (@{$patch->frus()}) {
        my $fruname  = "$fru->{locator}";
        my $fruclass = "$fru->{class}";
        print "    <FRU>";
        print "<NAME>$fruname</NAME>";
        print "<CLASS>$fruclass</CLASS>";
        print "</FRU>\n";
      }
    }
    print "  </DEVICE>\n";
  }
  print "</PATCH_UPGRADE_REPORT>\n";

}

#
# Clear Patch Backout Report
#
sub clearBackoutReport {
  print Client->http_OK();
  my $D = System->get_home() . "/DATA/tmp";
  unlink "$D/Downgrade";
  unlink "$D/Downgrade_pid";
  unlink "$D/Patchdowngrade";
  unlink "$D/Patchdowngrade_pid";
  return "OK";
}

#
# Generate Patch Upgrade Report
#
sub generateBackoutReport {
  print Client->http_OK();
  my $SID = "storade";
  my $command = System->get_home() . "/bin/ras_patchdowngrade -S $SID -b";
  system($command);
  sleep(1);
  return "OK";
}

#
# List Backout Patches
#
sub applyBackoutPatches {
  my($q) = @_;
 
  print Client->http_OK();

  my $SID  = "storade";
  my $command =  System->get_home() . "/bin/ras_downgrade -S $SID -U -b";
  system($command);
  sleep(1);

  print "OK";

}

#
# List Backout Patches
#
sub listBackoutPatches {
  my($q) = @_;
 
  print Client->http_OK();

  my $Config = PDM::ConfigFile->read();

  my $rep  = Process->read(undef, "Patchdowngrade");
  my $ppro = PPRO->parse($rep->{data}{report});

  if ($ppro->{ERRORS}) {
    print "<ERROR>error</ERROR>\n";
    return;
  }

  my $inv = Inventory->readInventory();
  my %IP; # map devives by ipno
  foreach my $d (@{$inv->getDevices()}) {
    $IP{$d->{ipno}} = $d;
  }

  my $State = State->getComponentState(0);

  print "<PATCH_UPGRADE_REPORT>\n";
  print "  <DATE>$rep->{date}</DATE>\n";
  foreach my $pp (@{$ppro->devices()}) {
    my $inv_d = $IP{$pp->key()};
    my $ip    = $pp->key();
    my $name  = $inv_d->{name};
    my $dev   = $Config->deviceByIP($ip);

    print "  <DEVICE>\n";
    print "    <NAME>$name</NAME>\n";
    print "    <IP>$ip</IP>\n";
    print "    <KEY>$dev->{key}</KEY>\n";
    print "    <TYPE>$dev->{type}</TYPE>\n";

    my $P = $pp->patches();

    my ($k, $sev);
    my $type = lc($pp->type());
    if ($type eq "sunos") {
      $k = "sp:" . System->hostid();
    } elsif ($dev) {
      $k = "$dev->{type}:$dev->{key}"
    } 
    $sev = 0;
    if (exists $State->{$k}) {
      $sev = int($State->{$k}[0] + 0.5);
    }
    print "    <ALARM_SEVERITY>$sev</ALARM_SEVERITY>\n";

    foreach my $patch (@$P) {
      my $pid = $patch->{patchID};
      my $syn = $patch->{synopsis};
      my $err = $pp->error($patch->{error});
      my $frus;
      print "    <PATCHID>$pid</PATCHID>\n";
      print "    <PATCH_SYNOPSIS>$syn</PATCH_SYNOPSIS>\n";
      foreach my $fru (@{$patch->frus()}) {
        my $fruname  = "$fru->{locator}";
        my $fruclass = "$fru->{class}";
        print "    <FRU>";
        print "<NAME>$fruname</NAME>";
        print "<CLASS>$fruclass</CLASS>";
        print "</FRU>\n";
      }
    }
    print "  </DEVICE>\n";
  }
  print "</PATCH_UPGRADE_REPORT>\n";

}

1;

