package Client::Discovery;
use Agent::HOST;
use Client;
use Debug;
use strict 'vars';
use Discover;

sub help {
  print Client->http_OK();
  print "#<pre>\n";
  print <<EOF;
 Http Syntax:

 http://<host>:7654/rashttp?GO=Client::Discovery::list&format=xml|tab

agent.0.hostid  80a3738d
agent.0.hostname        indy-90.ebay.sun.com
agent.0.ipno    129.147.50.117
agent.0.agent_version   2.2.I0.000
agent.0.role    M
agent.0.solution_model  6960
agent.1.hostid  83104545
agent.1.hostname        indy-156.ebay.sun.com
agent.1.ipno    10.4.56.156
agent.1.agent_version   2.1.05.002
agent.1.role    AM
agent.1.solution_model  3910
EOF
}

# SUBNET
# {method        => "Subnet", 
#  select_host   => local | host1 | ""
#  prefix        => "diag",
#  monitor       => "Y|N"
#  ip_list       => "ip_name,ip_addr,10.10.10,10.10.10.1-20",  
#  write_config  => 1
# }

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

  my $method          = $q->{method};        # DeviceFromIP, Inband, Subnet
  # ""=all, local=local, host1=slave
  my $opt_p;
  if (defined($q->{write_config})) {
    $opt_p = "-p";
  }

  my($renv, $devs, $hosts,$notifs) = PDM::ConfigFile->read();

  print Client->http_OK();
  system("/bin/rm -rf /var/opt/SUNWstade/DATA/Discover/*");

  if (lc($method) eq "subnet") {
     my $arg  = "-I\"$q->{ip_list}\"";
     Discover->ras_admin($q->{select_host}, "discover_subnet $opt_p $arg",
                         $renv, $hosts, "subnet", 
                            { prefix => $q->{prefix}, 
                          monitor_on => $q->{monitor},
                            } );

  } elsif (lc($method) eq "devicefromip") {
      Discover->ras_admin($q->{select_host}, "discover_deviceIP $opt_p ", 
                          $renv, $hosts, "deviceIP",
                            {     prefix => $q->{prefix},
                              monitor_on => $q->{monitor},
                            });

  } elsif (lc($method) eq "inband") {
       Discover->ras_admin($q->{select_host}, "discover_inband $opt_p ", 
                          $renv, $hosts, "inband",
                           {      prefix => $q->{prefix},
                              monitor_on => $q->{monitor},
                            });
  }

  # for sync
  sleep(5);

  print "<DISCOVERY>$method started</DISCOVERY>\n";
  
}

#
# Get the details (devices discovered) for a given discovery type
# $q->{type} = "deviceIP|subnet|inband"
#
sub details {
  my ($q) = @_;
  my $type = $q->{type};
  my $D = System->get_home() . '/DATA/Discover';
  print Client->http_OK();

  opendir(O1, $D);
  my @files = readdir(O1); closedir(O1);
  my ( $l);
  print "<DEVICES>\n";
  foreach my $f (@files) {

    if ( $f eq "." || $f eq ".." ) {
      next;
    }

    if ($type && $f !~ /^$type\.(.+)/) {
      next;
    }
    my($method, $agent) = split(/\./, $f);
    my $DEVS = Discover->read($f);
    foreach my $d (@$DEVS) {
        if ($d->{error}) {
          print "<ERROR>$d->{error}</ERROR>";
        } else {
          my $name = $d->{username} || $d->{name};
          print "  <DEVICE>\n";
          print "    <AGENT>$agent</AGENT>\n";
          print "    <DISCO_TYPE>$method</DISCO_TYPE>\n";
          foreach my $el (sort keys %$d) {
              next if (substr($el,0,1) eq "_");
              print  "    <" . uc($el) . ">" . Client->xmlEncode($d->{$el}) . "</" . uc($el) . ">\n";
          }
          print "  </DEVICE>\n";
      }
    }
  }
  print "</DEVICES>\n";

}

#
# Display list of found devices. &details=1 returns one entry per slave
#
sub displayList {
  my ($q) = @_;

  my $MODS = Modules->load("GUIAdmin");
  
  my $TOT = Discover->stats($q->{details});
  my $total_running;
  my (@array, $c1);
  print Client->http_OK();
  print "<DISCOVERIES>\n";
  foreach my $el (keys %$TOT) {
    my $r1 = $TOT->{$el}{start} - $TOT->{$el}{stop};
    $r1 = 0 if ($r1 < 0);
    $total_running += $r1;
    print "  <DISCOVERY>\n";
    print "    <DISCOVERY_MODE>".$el."</DISCOVERY_MODE>\n";
    print "    <AGENTS_RUNNING>".$r1."</AGENTS_RUNNING>\n";
    print "    <AGENTS_STOP>".$TOT->{$el}{stop}."</AGENTS_STOP>\n";
    print "    <AGENTS_PROCESSED>".$TOT->{$el}{processed}."</AGENTS_PROCESSED>\n";
    print "    <DEVICES_FOUND>".$TOT->{$el}{lines}."</DEVICES_FOUND>\n";
    my $qq;
    $qq->{type} = $el;
    details($qq);
    print "  </DISCOVERY>\n";
  }
  print "</DISCOVERIES>\n";

}

#
# Clear discovered devices.
#
sub clear {
  my($q, $post, $util) = @_;

  my $DIR = System->get_home() . "/DATA/Discover";
  opendir(OO, $DIR);
  my @files = readdir(OO); closedir(OO);
  foreach my $f (@files) {
   next if (substr($f,0,1) eq ".");
   unlink "$DIR/$f";
  }
  print Client->http_OK();
  print "<STATUS>OK</STATUS>\n";
}

#
# Process discovered devices.
#
sub process {
  my($q, $post, $util) = @_;

  my ($err, $all_running, $info) = Discover->process_discovery($q);
  print Client->http_OK();
  print "<STATUS>\n";
  print "  <INFO>".$info."</INFO>\n";
  print "  <ERROR>".$err."</ERROR>\n";
  print "  <STATUS>".$all_running."</STATUS>\n";
  print "</STATUS>\n";
}


sub ProbeLocal {
  my($q) = @_;
  my $format = $q->{format} || "tab";
  my $probe  = $q->{probe} || "inband";
  my $renv = System->get_renv();

  if ($renv->{active} eq "N") {
    print Client->error($format, 100, "Agent not started.");
    return;
  }

  my $dtype;

  if ($probe eq "inband") {
    $dtype = "discover_inband";
  }
  elsif ($probe eq "3510") {
    $dtype = "discover_3510";
  }
  elsif ($probe eq "a5k") {
    $dtype = "discover_a5k";
  }
  elsif ($probe eq "ip"){
    $dtype = "discover_deviceIP";
  }
  else {
    print Client->error($format, 101, "Unknown Probe [$probe]");
    return;
  }

  my $command =  System->get_home() . "/bin/ras_admin $dtype >> /dev/null 2>&1 &";
  Debug->logLine("Client::Discovery::ProbeLocal $command");

  if (system($command) == 0){
    print Client->http_OK();
    print "OK";
    return;
  }
  print Client->error($format, 101, "Error running discover command. " . $?);
}


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

  my($renv, $devices, $hosts, $notifs) = PDM::ConfigFile->read();

  print Client->http_OK();
  my $hostid = System->hostid();
  my $ip     = Util->name2ip();
  my $cnt = 0;
  my (%Ports, $not, $con);
  Agent::HOST->readPorts(\%Ports);
  foreach my $l (keys %Ports) {
    if ($Ports{$l} =~ /NOT/) {
       $not++;
    } else {
       $con++;
    }
  }

  if ($q->{format} eq "xml") {
    print <<EOF;
<?xml version ="1.0"?>
<DISCOVERY_REPORT>
  <AGENT ID="0">
     <VALUE ID="hostid">$hostid</VALUE>
     <VALUE ID="hostname">$renv->{hostname}</VALUE>
     <VALUE ID="ipno">$ip</VALUE>
     <VALUE ID="agent_version">$renv->{version}</VALUE>
     <VALUE ID="role">$renv->{role}</VALUE>
     <VALUE ID="solution_model">$renv->{solution_model}</VALUE>
     <VALUE ID="ports_connected">$con</VALUE>
     <VALUE ID="ports_notconnected">$not</VALUE>
  </AGENT>
EOF
    foreach my $h (@$hosts) {
       $cnt++;

       print <<EOF;
  <AGENT ID="$cnt">
     <VALUE ID="hostid">$h->{hostid}</VALUE>
     <VALUE ID="hostname">$h->{hostname}</VALUE>
     <VALUE ID="ipno">$h->{ipno}</VALUE>
     <VALUE ID="agent_version">$h->{version}</VALUE>
     <VALUE ID="role">$h->{role}</VALUE>
     <VALUE ID="solution_model">$h->{solution_model}</VALUE>
  </AGENT>
EOF
    }
    print "</DISCOVERY_REPORT>\n";

  } else {
    print "#<pre>\n";

    print <<EOF;
agent.0.hostid\t$hostid
agent.0.hostname\t$renv->{hostname}
agent.0.ipno\t$ip
agent.0.agent_version\t$renv->{version}
agent.0.role\t$renv->{role}
agent.0.solution_model\t$renv->{solution_model}
agent.0.ports_connected\t$con
agent.0.ports_notconnected\t$not
EOF
    foreach my $h (@$hosts) {
     $cnt++;

    print <<EOF;
agent.$cnt.hostid\t$h->{hostid}
agent.$cnt.hostname\t$h->{hostname}
agent.$cnt.ipno\t$h->{ipno}
agent.$cnt.agent_version\t$h->{version}
agent.$cnt.role\t$h->{role}
agent.$cnt.solution_model\t$h->{solution_model}
EOF
    }
    print "#Done.\n";
  }
}


  
1;
