package TO::Node;
#<copyright>
# ----------------------------------------------------------
# Sun Proprietary/Confidential Code
# Copyright 2001, Sun Microsystems, Inc. All rights reserved.
# ----------------------------------------------------------
#</copyright>

use Debug;
use Data::Dumper;
use strict;

use vars qw($GR_LIST);

sub leaf { 0 }

sub knownDevice {
  my($class, $dev) = @_;

  my $to_list = Modules->read("TO");
  foreach my $mod0 (@$to_list) {
     my $mod = "TO::$mod0";
     if ($mod->can("isKnownDevice")) {
         if ($mod->isKnownDevice($dev)) {
            return 1;
         }
     }
  }
  return 0;
}

# Uses all devices for the current hba
#      and current EncNodeWWN || NodeWWN
sub enclosureType {
  my($class, $devs) = @_;

  my $to_list = Modules->read("TO");
  foreach my $mod0 (@$to_list) {
     my $mod = "TO::$mod0";
     if ($mod->can("isEnclosureType")) {
         my $rc = $mod->isEnclosureType($devs);
         return $rc if ($rc);
     }
  }
  return undef;
}


sub topoPort {
  my($node, $portWWN, $hba, $Config, $devs, $dev_no) = @_;

  my($config_dev, $port) = $Config->deviceByWWN($portWWN);
  if ($config_dev) {
     return ($port);
  }

  my $pi = $node->{portInfo};
  my($x);
  for ($x=0; $x <= $#$pi; $x++) {
     my $p = $pi->[$x];
     if ($p->{PortWWN} eq $portWWN || $p->{LocalPortWWN} eq $portWWN) {
        return $x;
     }
  }
  return ($#$pi+1);
}


sub find_port {
  my($ix, $hba_path) = @_;
   my($port, $new);
  if (exists($ix->{portInfo}[0]{hba_path}) &&
             $ix->{portInfo}[0]{hba_path} eq $hba_path) {
     $port = 0;
  } elsif (exists($ix->{portInfo}[1]{hba_path}) &&
                  $ix->{portInfo}[1]{hba_path} eq $hba_path) {
     $port = 1;
  } elsif ($ix->{portInfo}[0]{hba_path}) {
     $port = 1; $new = 1;
  } else {
     $port = 0; $new = 1;
  }
  return ($port, $new);
}



sub find_port2 {
  my($node, $wwn) = @_;

  my $pi = $node->{portInfo};
  my($x);
  for ($x=0; $x <= $#$pi; $x++) {
     my $p = $pi->[$x];
     if ($p->{PortWWN} eq $wwn || ($p->{LocalPortWWN} eq $wwn)) {
        return $x;
     }
  }
  return $#$pi+1;
}


sub addFromConfig {
  my($class, $topo, $Config) = @_;

  my $devs = $Config->myDevices();

  foreach my $dev (@$devs) {
     next if ($dev->{type} ne $class->type());
     next if (!$dev->isMineToMonitor());
     $class->newFromDev($topo, $dev);
  }
}


# add ro the hosts and hosts_type array if the host or host_type is diff.
#
sub set_host_type {
  my($class, $node, $type, $host) = @_;

  if (!exists $node->{info}{host_type}) {
    $node->{info}{host}      = $host;
    $node->{info}{host_type} = $type;
  } else {
    if ($node->{info}{host_type} ne $type || $node->{info}{host} ne $host) {
       $node->{info}{hosts}[0] = $node->{info}{host};
       $node->{info}{hosts_type}[0] = $node->{info}{host_type};
       my $ht = $node->{info}{hosts};
       my $htt = $node->{info}{hosts_type};
       my $found = 0; my $x;
       for ($x=1; $x <= $#$ht; $x++ ) {
         if ($ht->[$x] eq $host && $htt->[$x] eq $type) {
            $found = 1; last;
         }
       }
       if (!$found) {
         my $j = $#$ht+1;
         $node->{info}{hosts}[$j]      = $host;
         $node->{info}{hosts_type}[$j] = $type;
       }
    }
  }
}


sub portLabel {
   my($node, $port) = @_;

   return "port-" . ($port+0);
}

sub revision {
  return "";
}

sub getPortId {
  my($class, $port) = @_;    #  0 / 1
  return "port.$port";
}


sub getPortCIMId {
  my($obj, $port) = @_;

  my(@xx) = split(/:/, $obj->{info}{name});
  return "$xx[1]." . $obj->getPortId($port);
}

sub zones { 
  my($h, $type) = @_; 
  if ($type) {
    if (exists($h->{zones}{$type})) {
       return $h->{zones}{$type};
    }
  } elsif (exists($h->{zones})) {
    return $h->{zones};
  }
  return undef;
}

sub port     { 
   my($h, $port) = @_;
   if (defined($port)) {
     my $p = $h->{port};
     return $p->[$port];
   } else {
     return $h->{port};
   }
}
sub portInfo { 
  my($h , $port) = @_;
  my $pi = $h->{portInfo} ;
  if (defined($port)) {
    return $pi->[$port];
  } else {
    return $pi;
  }
}

sub info     { 
     my($h, $val) = @_; 
     if ($val) {
         return $h->{info}{$val}
     } else {
         return $h->{info};
     }
}

sub diskInfo { 
     my($h) = @_; return $h->{diskInfo} }
sub volInfo  { 
     my($h) = @_; return $h->{volInfo} }

sub volInfoHost  { 
     my($h) = @_; return $h->{volInfoHost} }


sub name {
  my($obj) = @_;
  return $obj->{info}{name};
}


# last part of name (key)
sub key {
  my($obj) = @_;

  my(@xx) = split(/:/, $obj->{info}{name});
  return $xx[1];
}


sub id {
  my($obj) = @_;

  Debug->err("Error: id must be implemented for " . $obj->name());
}

sub boxName {
  my($obj) = @_;
  return $obj->{info}{BoxName};
}

sub getDevice {
  my($obj) = @_;
  my $Config = PDM::ConfigFile->read();
  return $Config->deviceByKey($obj->key());
}

sub getPortLink {
  my($sw, $port) = @_;

  my $p = $sw->port();
  return undef if (!$p);
  return $p->[$port];
}


sub class {
  my($obj) = @_;
  return $obj->info("class");
}

sub class0 {
  my($obj) = @_;
  my $cl = $obj->info("class");
  my $ix = index($cl, ".");
  $cl = substr($cl,0,$ix) if ($ix > 0);
  return $cl;
}

sub type {
  my($obj) = @_;
  return $obj->info("type");
}

sub toString {
  my($obj) = @_;

  return Dumper($obj);
}

# zone = "hd0"
sub getPortsInZone {
  my($node, $zone) = @_;
  my $z = substr($zone,0,2);
  my $n = substr($zone,2) + 0;

  if (exists($node->{zones}{$z})) {
    return $node->{zones}{$z}[$n]; 
  } else {
    return undef;
  }
}

sub getZoneList {
  my($node, $type) = @_;
  my %H;
  if (!exists($node->{zones})) {
     return undef;
  }
  my $z = $node->{zones};
  my $hd = $z->{hd};
  my $x;
  if ($hd && (!$type || $type eq "hd") ) {
   for ($x=0; $x <= $#$hd; $x++) {
     next if (!$hd->[$x]);
     $H{"hd$x"} = $hd->[$x];
   }
  }
  my $sl = $z->{sl};
  if ($sl && (!$type || $type eq "sl") ) {
   for ($x=0; $x <= $#$sl; $x++) {
     next if (!$sl->[$x]);
     my $ix = index($sl->[$x], " ");
     foreach my $k (%H) {
       if (index(" $H{$k} ", " " . substr($sl->[$x],0,$ix+1)) >= 0) {
          $H{"$k.sl$x"} = $sl->[$x];
       }
     }
   }
  }
  my $ns = $z->{ns};
  if ($ns && (!$type || $type eq "ns") ) {
   for ($x=0; $x <= $#$ns; $x++) {
     next if (!$ns->[$x]);
     my $ix = index($ns->[$x], " ");
     foreach my $k (%H) {
       if (index(" $H{$k} ", " " . substr($ns->[$x],0,$ix+1)) >= 0) {
          $H{"$k.ns$x"} = $ns->[$x];
       }
     }
   }
  }
  return \%H;
}

sub ipAddr {
  my($sw) = @_;
  return undef;
}



sub statusFunc {
  my($class, $name, $State, $arg, $node) = @_;

  my $Comp    = $State->components($name);
  my $i       = $Comp->value("e");
  my $iIB     = $Comp->value("ib");

  my $enc     = TO->val($i->[0], $iIB->[0]);
  my $encInfo = TO->val2(1,$i, $iIB);

  my ($port, $disk, $diskInfo);
  my ($portInfo, $other, $otherInfo);

  foreach my $el (keys %$Comp) {
     $Comp->summ($el, \$other, \$otherInfo);
  }

  return ($enc, $port, $disk, $other, $encInfo, $portInfo, $diskInfo, $otherInfo);
}

  



1;
