package Client::SEControl;
use Html;
use strict;
use MG::T3;
use MG::DSP;
use MG::Util;
use PDM::ConfigFile;
use Service::Fru;
use Process;
use Client;
use Inventory;


sub runDSPCommand {
 my($q) = @_;
 my $command = $q->{command};
 my $key = $q->{deviceID};

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

 print Client->http_OK();

 if($dev) {
   print Client->error("xml", 1415, "cannot find this device $key");
   return;
 }

 if (!Util->ping($dev->{ipno})) {
   print Client->error("xml", 1416, "cannot ping the dsp " . $dev->{ipno});
   return;
 }
 my $dsp = MG::DSP->new($dev); 
 my($err, $t) = $dsp->connect();

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

 my($rc);
 my @L = split(/,/, $command);
 $rc = $dsp->runCommand(\@L);
 print "<SEACTION>" . Client->xmlEncode($rc->report()) . "</SEACTION>";
 $dsp->runCommand(["exit"]);

}

sub runHostCommand {
 my($q) = @_;
 my $command = $q->{command};
 my ($err, $com) = Util->run_command($command, undef, 30, {cache => 0} );

 print Client->http_OK();

 if ($err) {
   print Client->error("xml", 1417, $err);
 } else {
   print "<SEACTION>" . Client->xmlEncode(join("\n", @$com)) . "</SEACTION>";
 }

}

sub getNewArrays {
  my($renv, $devs) = PDM::ConfigFile->read();
  my(%TAKEN);
  foreach my $d (@$devs) {
    if ($d->{name} =~ /^array(\d+)/) {
      $TAKEN{$d->{name}} = 1;
    }
  }
  my $new ;
  my ($l);
  open(O, "/etc/hosts");

  print Client->http_OK();
  while ($l = <O>) {
     my($ip0, $name, $rest) = split(/\s+/, $l);
     if ($name =~ /^array/ && !$TAKEN{$name}) {
       print "<ARRAY ID=\"$name\">$name</ARRAY> \n";
     }
  }
}

sub getBootStatus {
  my $ID = "array_boot";
  my $status = Process->status(undef, $ID);
  my $info   = Process->read(undef, $ID);
  my $trace  = $info->{data}{trace};

  print Client->http_OK();

  print "$status";

}

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

  my $ID = "array_boot";
  my $INFO;

  my $time = $q->{time} + 15;
  $time = 60 if ($time > 60);

  my $status = Process->status(undef, $ID);
  my $age = Process->age($ID);

  if($status =~ /Running/) {
    print Client->error("xml", 1405, "the boot process is running");
    return;
  }

  my $array = $q->{array};
  my $password = $q->{password};
  

#  my $array = $q->{array}; # diag78
  my $cmd = System->get_home() . 
    "/sysbin/array_boot -i $array -p \"$password\"";
  system("$cmd&");

  print Client->http_OK();
  print "<SEACTION>OK</SEACTION>";
}


sub arrayLocate {
  my($q) = @_;
  my $fru = $q->{fruID};
  my $key = $q->{deviceID};
 
  my $Config = PDM::ConfigFile->read();
  my $dev = $Config->deviceByKey($key);

  print Client->http_OK();

  if (!$dev) {
    print Client->error("xml", 1401, "device not found");
    return;
  }

  my $t3 = MG::T3->new($dev);
  
  my $rc;
  if ($q->{NOLOCATE}) {
     $rc = $t3->array_nolocate($fru);
  } else {
     $rc = $t3->array_locate($fru);
  }

  if ($rc->error()) {
    print Client->error("xml", 1402, $rc->error());
  } elsif ($rc->warning()) {
    print Client->error("xml", 1403, $rc->warning());
  } else {
    print "<SEACTION>OK</SEACTION>";
  }
}

sub allStat {
  my($q) = @_;
  my $command = $q->{fruID};

  my $renv = System->get_renv();
  my ($renv2, $devs) = PDM::ConfigFile->read();

  print Client->http_OK();

  foreach my $d (@$devs) {
     next if ($d->{type} ne "6020");
     my $t3 = MG::T3->new($d);
     my $rc = $t3->fru_stat($command);
     print $rc->report2html();
  }
}

sub arrayDisk {
  my($q) = @_;
  &arrayFRU($q, "disk");
}

sub arrayController {
  my($q) = @_;
  &arrayFRU($q, "controller");
}

sub arrayLoopcard {
  my($q) = @_;
  &arrayFRU($q, "loopcard");
}

sub arrayPower {
  my($q) = @_;
  &arrayFRU($q, "arraypower");
}

sub arrayBattery {
  my($q) = @_;
  &arrayFRU($q, "arraybattery");
}

sub fruStat {
  my($q) = @_;
  &arrayFRU($q, "fru");
}

sub arrayFRU {
  my($q, $type) = @_;
  my $fru = $q->{fruID};
  my $key = $q->{deviceID};

  my $Config = PDM::ConfigFile->read();
  my $dev = $Config->deviceByKey($key);
 
  print Client->http_OK();

  if (!$dev) {
    print Client->error("xml", 1401, "device not found");
    return;
  }

  my $t3 = MG::T3->new($dev);
  my $rc;

  if ($type eq "disk") {
    $rc = $t3->pre_disk_disable($fru);
  } elsif ($type eq "controller") {
    $rc = $t3->pre_controller_disable($fru);
  } elsif ($type eq "loopcard") {
    $rc = $t3->pre_loopcard_disable($fru);
  } elsif ($type eq "arraypower") {
    $rc = $t3->pre_arraypower_disable($fru);
  } elsif ($type eq "arraybattery") {
    $rc = $t3->pre_arraybattery_disable($fru);
  } elsif ($type eq "fru") {
    $rc = $t3->fru_stat($fru);
  }

  print $rc->report2html();

  if ($rc->error()) {
    print $rc->error();
  }

  if ($rc->warning()) {
    print $rc->warning();
  }
}

sub dsp {
  my($q) = @_;
  my $fru = $q->{fruID};
  my $key = $q->{deviceID};
 
  my $Config = PDM::ConfigFile->read();
  my $dev = $key ? $Config->deviceByKey($key) : $Config->deviceByType("dsp");
 
  print Client->http_OK();

  if (!$dev) {
    print Client->error("xml", 1401, "device not found");
    return;
  }

  my $dsp = MG::DSP->new($dev);
  my $rc = $dsp->pre_disable($fru);

  print $rc->report2html();

  if ($rc->error()) {
    print $rc->error();
  }

  if ($rc->warning()) {
    print $rc->warning();
  }

}

sub getArrays {
  my($renv, $devs, $host,$notifs, $Config) = PDM::ConfigFile->read();

  print Client->http_OK();
  foreach my $d (@$devs) {
    next if ($d->{type} !~ /6[01]20/);
    print "<ARRAY ID=\"$d->{ipno}\">" . $d->{name} . "</ARRAY>\n";
  }

}

sub configure {
  my($q) = @_;
  
  my $ipno = $q->{ipno};
  
  my $command = "configure";
  $command = "unconfigure" if($q->{UNCONF});

  my ($err, $rc) = Inventory->run_vmcfg0($ipno, $command);

  print Client->http_OK();
  if($err) {
    print Client->error("xml", 1412, Client->xmlEncode("Error on '$command': $err"));
  } else {
    print "<SEACTION>" . Client->xmlEncode("'$command' command executed on device $ipno:@$rc") . "</SEACTION>";
  }
}


sub saveInventory {
  my($q) = @_;
  my $inv = Inventory->readInventory($q->{F});
  print Client->http_OK();
  if ($inv) {
    $inv->writeInventory(undef, 1);
    $inv->writeConfig("write"); 
    unlink $q->{F};
    print "XMLSTART\n";
    print "<SEACTION>OK</SEACTION>";
  } else {
    print "XMLSTART\n";
    print Client->error("xml", 1410, "file $q->{F} not found");
  }
}

sub compareInventory {

  my $renv = System->get_renv();
  my $model = $renv->{solution_model};
  my $short = System->hostname();

  print Client->http_OK();
  my $oinv = Inventory->readInventory();
  my($trace_out, $inv) = Inventory->readMaserati($short, undef, 1, 1, $model);

  $inv->{model} = $model;
  my $F = "/tmp/inv_upd_$$";
  $inv->writeInventory($F, 1, 1);
  
  print "XMLSTART\n";
  print "<trace>" . Client->xmlEncode($trace_out) . "</trace>\n";
  print "<file>$F</file>\n";
  my $devs = $inv->getKeys();
  my $odevs = $oinv->getKeys();
  foreach my $k (keys %$devs) {
    my $d = $devs->{$k};
    if (exists($odevs->{$k})) {
      print "<device id=\"$k\" name=\"$d->{name}\" type=\"$d->{type}\" ipno=\"$d->{ipno}\"  change=\"update\"> \n";
      my $frus = $d->frus();
      my $ofrus   = $odevs->{$k}{frus};
      my $changes;
      foreach my $fruid (keys %$frus) {
	my $fru = $frus->{$fruid};
	my $ofru = $ofrus->{$fruid} || {};
	foreach my $entry (keys %$fru){
	  if (!exists($ofru->{$entry})) {
	    #$changes .= "-Fru $fruid:$entry has been added.<br>";
	    print "<fru change=\"add\">\n";
	    print "<id>$fruid</id>\n";
            print "<entry>$entry</entry>\n";
            print "</fru>\n";
	    last;
	  }elsif ($fru->{$entry} ne $ofru->{$entry}) {
	    #$changes .= "-$entry of $fruid changed from '$ofru->{$entry}' to '$fru->{$entry}'<br> ";
            print "<fru change=\"update\">\n";
	    print "<id>$fruid</id>\n";
            print "<entry>$entry</entry>\n";
            print "<from>$ofru->{$entry}</from>\n";
            print "<to>$fru->{$entry}</to>\n";
            print "</fru>\n";
	  }
	}
      }
      foreach my $fruid (keys %$ofrus) {
	my $ofru = $ofrus->{$fruid};
	my $fru = $frus->{$fruid} || {};
	
	foreach my $entry (keys %$ofru){
	  if (!exists($fru->{$entry})) {
	    #$changes .= "-Fru $fruid:$entry has been removed.<br>";
	     print "<fru change=\"remove\">\n";
	    print "<id>$fruid</id>\n";
            print "<entry>$entry</entry>\n";
            print "</fru>\n";
	    last;
	  } # else we have already compared versions above
	}
      }
      print "</device> \n";    
      
    } else {
      print "<device id=\"$k\" name=\"$d->{name}\" type=\"$d->{type}\" ipno=\"$d->{ipno}\" change=\"add\" /> \n";
    }
  }

  foreach my $k (keys %$odevs) {
    if (!exists($devs->{$k})) {
      my $d = $odevs->{$k};
      print "<device id=\"$k\" name=\"$d->{name}\" type=\"$d->{type}\" ipno=\"$d->{ipno}\" change=\"remove\" /> \n";
    }
  }
}

1;
