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

use base 'TO::STORAGE';
use strict;
use State;
sub leaf { 1 }

sub type { 'a5k' }

sub isKnownDevice {
  my($class, $dev) = @_;
  if ($dev->{ProductID} =~ /SENA/ || $dev->{ENCNodeWWN} ) {
     return 1;
  }
  return 0;
}

sub isEnclosureType {
  my($class, $devs) = @_;
  foreach my $dev (@$devs) {
     if ($dev->{ProductID} =~ /SENA/) {
        return 'TO::A5K';
     }
  }
  return undef;
}

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

  return $dev->{ProductID} eq "SENA" ? "P" : "D";
}



# this controls the position of the port in the {port}[] 
# based on the connectedOn value

sub topoPort {
  my($node, $portWWN, $hba, $Config,$devs, $dev_no) = @_;
  my %L = ('B1' => 0, 'A1' => 1, 'B0' => 2, 'A0' => 3);
  my $dev = $devs->[$dev_no];
  my $port;

  if ($dev->{ConnectedOn}) {
     $port = $L{$dev->{ConnectedOn}};

  } elsif ($dev->{LogicalPath} =~ /ses(\d)/) {
     $port = $1;

  } else {
     $port = 0;
  }
  return ($port, ,$port);

# return $node->SUPER::topoPort($portWWN);
}





# called by Discover::HBAApi
sub newFromDev {
  my($class, $to, $dev, $arg) = @_;

$DB::single=1;
  my $renv = System->get_renv();
  my $host = $renv->{hostname};
  my $k = $dev->{type} . ":" . $dev->{key};
  my $exist = $to->nodeByName($k);

  my $storages  =  $to->[2];
  my $key       = $dev->{key};

  my $obj = $exist || {};
  $obj->{info}{type}    = $dev->{type};
  $obj->{info}{class}   = 'storage.' . $dev->{type};
  $obj->{info}{name}    = "$dev->{type}:$key";
  $obj->{info}{BoxName} = $dev->{name};
  $obj->{info}{host}    = $host;
  $obj->{info}{host_type} = "ib";
  $obj->{info}{VendorID}= "SUN";
  $obj->{info}{LGroup}  = $dev->{type};
  $obj->{info}{PortWWN} = $dev->{wwn};
  $obj->{info}{NodeWWN} = $dev->{wwn};
  $obj->{port}          = [] if (!exists $obj->{port});
  $obj->{portInfo}      = [] if (!exists $obj->{portInfo});
  # Ports are always => B1 = 0, A1 = 1, B0 = 2, A0 = 3;
  #  Back of machine looks like:
  #
  #   A1  A0        => 1   3
  #   B1  B0	    => 0   2

  my $base = substr($dev->{wwn},0,15);
  my $base_end = substr($dev->{wwn}, -1, 1);
  my $end_digit;
  my $portw;

  #B1 -> 0
  $end_digit = $base_end + 4;
  $portw = sprintf("%s%x", $base, $end_digit);
  $obj->{portInfo}[0]   = {
     PortWWN        => $portw,
     LocalPortWWN   => $portw,
     PortLabel      => 0,	
     realPort       => "B1",
  };
  # A1 -> 1
  $end_digit = $base_end + 2;
  $portw = sprintf("%s%x", $base, $end_digit);
  $obj->{portInfo}[1]   = {
     PortWWN        => $portw,
     LocalPortWWN   => $portw,
     PortLabel      => 1,
     realPort       => "A1",
  };

  # B0 -> 2	
  $end_digit = $base_end + 3;
  $portw = sprintf("%s%x", $base, $end_digit);
  $obj->{portInfo}[2]   = {
     PortWWN        => $portw,
     LocalPortWWN   => $portw,
     PortLabel      => 2,
     realPort       => "B0",
  };

  # A0 -> 3	
  $end_digit = $base_end + 1;
  $portw = sprintf("%s%x", $base, $end_digit);
  $obj->{portInfo}[3]   = {
     PortWWN        => $portw,
     LocalPortWWN   => $portw,
     PortLabel      => 3,
     realPort       => "A0",
  };
		 
    
  bless($obj, 'TO::'. uc($dev->{type}));

  $storages->{"$dev->{type}:$key"} = $obj;
  return $obj;
}




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

   if ($port == 0) {
      return "ses-B1";
   } elsif ($port == 1) {
      return "ses-A1";
   } elsif ($port == 2) {
      return "ses-B0";
   } elsif ($port == 3) {
      return "ses-A0";
   }
}
  
      

#
# used to look in the State db
#
sub getPortId {
  my($class, $port) = @_;    # 0 / 1
  if ($port == 0) {
     return 'interface_board.B';
  } else {
     return 'interface_board.A';
  }
}

sub getDiskList {
  my($node) = @_;
  my (@L, $x, $y);
  foreach my $x ('disk_front','disk_rear') {
     for ($y=0; $y <= 10; $y++) {
       push(@L, "$x.$y");
     }
  }
  return \@L;
}


sub statusFunc {
  my($class, $name, $State, $arg, $node) = @_;
  my($type);
  my $Comp = $State->components($name);
  my $i = $Comp->value("ib");
  my $enc = $i->[0];
  my $encInfo = $i->[1];

  ($type, $name) = split(/:/, $name);
  $name = "a5k:$name";

  my($port, $portInfo, $p1, $p2);
  my ($map, @MAP);
  if ($node->{info}{gbic_map}) {
     $map =1;
     @MAP = split(/,/, $node->{info}{gbic_map});
  }
  my $cnt = 0;
  my $array;
     $array->{'B.gbic1'} = "B1";
     $array->{'A.gbic1'} = "A1";
     $array->{'B.gbic0'} = "B0";
     $array->{'A.gbic0'} = "A0";


  foreach my $e ('B.gbic1','A.gbic1','B.gbic0','A.gbic0') {
     my $ab = substr($e,0,1);
     my $portvalue = "[" . $array->{$e} . "]";
     if ($map && ($MAP[$cnt] == -1)) {
        $port .= "-1,";
        $portInfo .= "$portvalue,";
     } elsif ($e =~ /0/) {
         $p1        = $Comp->value("interface_board.$ab",0) ;
         $p2        = $Comp->value("interface_board.$e",0);
         $port     .= TO->val($p1, $p2) . ",";
	 
         $portInfo .= $portvalue . ($Comp->value("interface_board.$ab",1) ||
                       $Comp->value("interface_board.$e",1)) . ",";
     } else {
         $port     .= $Comp->value("interface_board.$e",0) . ",";
         $portInfo .= $portvalue . $Comp->value("interface_board.$e",1) . ",";
     }
     $cnt++;
  }
  my ($other, $otherInfo);
  $Comp->other([], \$other, \$otherInfo);

  my($disk, $diskInfo);
  $map = 0;
  if ($node->{info}{disk_map}) {
     $map =1;
     @MAP = split(/,/, $node->{info}{disk_map});
  }
  my $o1 = 0;
  foreach my $u ('disk_front','disk_rear') {
     my($d);
     for ($d=0; $d <= 10; $d++) {
         if ($map && ($MAP[$d+$o1] == -1)) {
           $disk .= "-1,";
         } else {
           $disk .= $Comp->value("${u}.$d",0) . ",";
         }
         $diskInfo .= $Comp->value("${u}.$d",1) . ",";
     }
     $o1 = 11;
  }

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

}


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

  return("a,A5K,4/BA,11,f/r,_,,E0F0F0/a5k.gif", "A5K", 2);
}



sub getLogicalPaths{
  my($self) = @_; 
  my @paths;
  my $diskInfo = $self->diskInfo();
  foreach my $disk (keys %$diskInfo) {
    my $Disk = $diskInfo->{$disk};
    push(@paths, split(/\|/,$Disk->{LogicalPath}));
  }
  return @paths;
}


1;


