# $Id: Discovery.pm,v 1.4 2004/11/11 19:55:45 jkremer Exp $
# Copyright 2004, Sun Microsystems, Inc. All rights reserved.
package Java::Discovery;

use Java::JrexMsg;
use Java::JrexClient;
use System;
use Debug;
use strict;

# Search for java probe devices given an ip address.
# INPUT:  Ip address to search.
# OUTPUT: an array of hashes with each has having disovered properties.
sub ipSearch {
  my($class, $ip) = @_;
# Currently not implemented!
}

# Search for device that matches properties from an inband fcpTarget search
# INPUT: Inband FCP Target properties.
# OUTPUT:  an array of hashes with each has having disovered properties.
sub fcpTargetSearch {
  my($class, $search) = @_;
# Currently not implemented!
}


# Search for a device of the given type and input search properties.
# INPUT: Device type and hashmap with search properties.
# OUTPUT: an array of hashes with each has having discovered properties.
sub deviceSearch {
  my($class, $search, $devType) = @_;
  my @D;

  my $client = new Java::JrexClient();

  use Data::Dumper;
  my $probeResults = $client->invoke
  ("com.sun.netstorage.fm.storade.agent.helper.DeviceHelper",
	"discover",
	[$devType, $search]
  );

  if (!$probeResults){
	 my %R;
	 $R{error} = $client->error;
	 push(@D, \%R);
	 return  \@D;
  }

  if ($probeResults->{status}){
	 if ("#OK" eq $probeResults->{status}){
		my $devs = $probeResults->{devices};
		my $index;
		for($index = 0; $index <= $#$devs; $index++) {
		  my $props = $devs->[$index];
		  if ((!$props->{class})||(!$props->{type})){
			 my %R;
			 $R{error} = "ERROR probe missing type/class properties.";
			 push(@D, \%R);
		  } else {
			 push(@D, $props);
		  }
		}
	 }
	 elsif ("#ERROR" eq  $probeResults->{status}){
		my %R;
		$R{error} = $devType . ":" . $probeResults->{message};
		push(@D, \%R);
	 }
  }


  # Old Java API returns ProbeResult[]
  else {

	 my $index;
	 for($index = 0; $index <= $#$probeResults; $index++) {
		my $props = $probeResults->[$index];
		my $discoStatus = $props->{_DISCOVER_STATUS};
		
		if ("#OK" eq $props->{_DISCOVER_STATUS}){
		  delete $props->{_DISCOVER_STATUS};
		  if ((!$props->{class})||(!$props->{type})){
			 my %R;
			 $R{error} = "ERROR probe missing type/class properties.";
			 push(@D, \%R);
		  } else {
			 push(@D, $props);
		  }
		}
		else {
		  my %R;
		  my $discoMsg    = $props->{_DISCOVER_MESSAGE};
		  $R{error} = $discoStatus . ": " . $discoMsg;
		  push(@D, \%R);
		}
	 }
  }

  return \@D;
}


sub addToConfig {
  my ($class, $q, $devType) = @_;
  my @nodes;
  my $err;
  my $status;

  my $rcs = Java::Discovery->deviceSearch($q, $devType);
  foreach my $rc (@$rcs) {
    my $key = $rc->{key};
    if (!$key) {
      $err = Error->warning("cannot_discover",  
			    "on $q->{ip}: $rc->{error}");
      last;
    }
    ($err, $status) = Java::Discovery->addDevice($rc);
    if ($err){
      last;
    }
    if ($status eq "added"){
      push(@nodes, $rc);
    }
  }
  return ($err, \@nodes);
}


# Add a found device to the configuration
sub addDevice {
  my ($class, $rc) = @_;

  my $x;
  my $active = "Y";
  my @nodes;
  my $newdev;
  my $err;

  my($renv, $devs, $hosts,$notifs) = PDM::ConfigFile->read();
  my $key = $rc->{key};
  my $type = $rc->{type};

  my %THERE;
  foreach $x (@$devs) {
    if (index($type, $x->{type}) >= 0) {
      $THERE{$x->{key}} = 1;
    }
    # may want to merge here.
  }

  # New device: add to configuration.
  if (!$THERE{$key}) {
    $x = $#$devs + 1;
    if (!$rc->{active}){
      $rc->{active} = $active;
    }
    if (!$rc->{mgmtLevel}){
      $rc->{mgmtLevel} = "D";
    }
    PDM::ConfigFile->addDevice($devs, $rc);

    Logic->clearSlave($rc->{host}, $hosts);
    push(@nodes, $devs->[$x]);

    if (!PDM::ConfigFile->write( $renv, $devs, $hosts,$notifs)) {
      $err = Error->error(101);
    }
    return ($err, "added");
  }
  else {
     # may want to merge and update properties here.
    return ($err, "merged");
  }
}


1;
