package Discover::Luxadm;
use System;
use strict;
use DiscoveryObject;
use Discover;
use HBAApi;

sub REGISTER {
  my($class) = @_;

  return { types  => "a5k,tape",
          sysDesc => 0,
          fromIP  => 0,
          inBand  => 1,   # inband || broadcast discovery (no ip)
     disco_level  => 2,   # thick-client discovery
          };
}


# categorize the output of disk_inquiry.
# use it to find a5k, tape, v880disk, internal
# use disk_inquiry to avoid categorizing internal disk wrongly.

# was called Logic::Inband::get_devices($q)

sub discoverInBand {
  my($class, $q) = @_;

  my($renv, $dev, $host,$notifs) = PDM::ConfigFile->read;
  my $G = Labels->read();
  my $master = Util->findMaster;
  my $hname = $master ? $renv->{hostname} : "";

  my($TO) = $renv->{"timeout.luxadm"} + 10;
  my $probe = "/usr/sbin/luxadm probe";
  my $inq   = System->get_home() . "/bin/disk_inquiry";

  my($err, $inq_list) = Util->run_command($inq,"luxprobe.txt", $TO);
  my($x, @INQ, $in);
  for ($x=0;$x <= $#$inq_list; $x++) {
     $inq_list->[$x] =~ s/\s+/ /g;
     my $l = $inq_list->[$x];
     next if ($l =~ /^\s*$/);
     if ($l =~ /Location/) {
        $in =1;
     } elsif ($in) {
       my $type = "internal";
       if ($l =~ /SUN T3/) {
         $type = "t3";
       } elsif ($l =~ /SUN T4/) {
         $type = "6120";
       } elsif ($l =~ /SUN SESS/) {
         $type = "ve";
       } elsif ($l =~ /SUN PSX/ || $l =~ /SE6920/ ) {
         $type = "dsp";
       } elsif ($l =~ /HITACHI/) {
         $type = "9900";
       } elsif ($l =~ /StorEdge 35/) {
         $type = "3510";
       } elsif ($l =~ /StorEdgeA3500FCd/) {
         $type = "a3500fc";
       }

       push(@INQ, [$type, $l]);
     }
  }

  my($err, $out) = Util->run_command($probe,"luxprobe.txt", $TO);
  my(@L);
  if ($err) {
     my $obj = DiscoveryObject->error("INBAND", "luxadm probe failed $err");
     push(@L, $obj);
  }
  my(@INT, $name, $wwn, %LIST, $y);
  for ($y = 0; $y <= $#$out; $y++) {
    my $l = $out->[$y];
    my $type;
    if ($l =~ /SENA/) {
      $type = "a5k";
    } elsif ($l =~ /Tape /) {
      $type = "tape";
    } elsif ($l =~ /SUNWGS INT FCBPL/) {
      $type = "v880disk";
    }
    if ($type) {

      if ($l =~ / Name:(.+)\s+Node WWN:([0-9a-f]+)/) {
        $name = Util->rtrim($1);
        $wwn = Util->rtrim($2);
        $name = $wwn if (!$name);
        my $obj =  DiscoveryObject->newFromString(
                "storage.$type|$type||$wwn|$wwn|||$name|||$hname");
        push(@L, $obj);


      } elsif ($l =~ /Node WWN:([0-9a-f]+)/) {

        $wwn = Util->rtrim($1);
        $name = "$type-" . substr($wwn,-4);
	my $portwwn = $wwn;

	if($type eq "tape"){
           my($err, $L) = HBAApi->run1({
                   cache_delay => $renv->{"hbaapi.dis_hba.delay"} || 5,
                       command => "dis_hba" ,
                   });
           my ($hba_list, $switch_list) = HBAApi->parse($L);

	   foreach my $hba (@$hba_list) {
	      my $devs = $hba->{deviceInfo};
	      foreach my $dev (@$devs) {
                 if ($wwn eq $dev->{NodeWWN}) {
		     $portwwn = $dev->{PortWWN};
		 }
	      }
	   }
	}

        my $obj =  DiscoveryObject->newFromString(
                    "storage.$type|$type||$portwwn|$wwn|||$name|||$hname");
        push(@L, $obj);
      }
    } elsif ($l =~ /Node WWN:([0-9a-f]+)\s+Device Type:Disk/) {
       my $w = $1;
       my $w2 = uc($w);
       my $short = "[0-9A-F][0-9A-F][0-9A-F][0-9A-F]" . 
                   substr($w2,4,3) . "[0-9A-F][0-9A-F][0-9A-F][0-9A-F]" .
                   substr($w2,11);
       my ($skip, $next);
       if ($out->[$y+1] =~ /Logical Path/) {
         $next = $out->[$y+1];
         my $ix1 = rindex($next, "/");
         $next = substr($next, $ix1+1, -3);
       }
       foreach my $l2 (@INQ) {
         if ($l2->[1] =~ /$short/ && $l2->[0] ne "internal") {
            $skip = 1;
            last;
         } elsif ($next && $l2->[1] =~ /$next/ && $l2->[0] ne "internal"){
            $skip = 1;
            last;
         }
       }
        
       if (!$skip && !$LIST{$w}) {
         push(@INT,$w);
         $LIST{$w} = 1;
       }
    }
  }
#  class,type,ip,wwn,key,wwn2,model,name,label,name2,host

  my $key = "ID" . System->hostname();
  my $name = "ID-" . System->shortHostname();
  if ($#INT >= 0) {
     my $ws = join(",", @INT) . ",";
     my $obj =  DiscoveryObject->newFromString(
        "storage.internal|internal||$key|$key|$ws||$name|||$hname");
     push(@L, $obj);
  }
  foreach my $obj (@L) {
     Discover->updateTopoDevice($obj);
  }
  return \@L;

}




1;
