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

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

sub isKnownDevice {
  my($class, $dev) = @_;
  return 1 if ($dev->{ProductID} =~ /StorEdge \d+/);
}

# $dev_no start at 0.
sub topoPort {
  my( $node, $portWWN, $hba,$Config, $devs, $dev_no) = @_;
  my $type = $node->{info}{type};
  my $port;
  if (index(",3310,3320,3310jbod,3120jbod,", ",$type,") >= 0 && !$node->{port}[0]) {
     $port = 0;
  } elsif (index(",3310,3320,3310jbod,3120jbod,", ",$type,") >= 0) {
     $port = 0;
  } else {
     $port = substr($portWWN,1,1)  - 1;
     return ($port, $port, $port);
  }
  if ($port < 0) {
     $port = 0;
  }
  return ($port);
}


sub portLabel {
  my($class, $port) = @_;
  return "port-$port";
}

sub getPortCIMId {
  my($node , $port) = @_;    #  0 / 1
  my $pi = $node->portInfo();
  return $pi->[$port]{PortWWN};
}

# $topo, $host, $dev, $arg 

sub newFromDev {
  my($class, $to, $dev, $arg) = @_;

  my $renv = System->get_renv();
  my $host = $renv->{hostname};
  
  my $k = $dev->{type} . ":" . $dev->{key};
  my $exists = $to->nodeByName($k) || $to->nodeBySynonym($dev);

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

  my $obj = $exists || {};
  my $org_name          = $obj->{info}{name};
  $obj->{info}{type}    = $type;
  $obj->{info}{class}   = "storage.$type";
  $obj->{info}{name}    = "$type:$key";
  $obj->{info}{NodeWWN} = $dev->{wwn} if ($dev->{wwn});
  $obj->{info}{BoxName} = $dev->{name};

  TO->host_array2($obj->{info}, {host => $host, host_type => $arg->{host_type} || "ib"});

  $obj->{info}{VendorID}= "SUN";
  $obj->{info}{LGroup}  = "Sun $type";
  $DB::single= 1;
  require Agent::3310;
  my $use_name;
  if(length($dev->{ipno}) > 1){
     $use_name = $dev->{ipno};
  }else{
     $use_name = $dev->{path};
  }
  my $report;
  if ($arg->{report}) {
     $report = $arg->{report};
  } else {
     my $rc  = Agent::3310->getWWN($use_name);
     if ($rc->{error}) {
        Debug->print1("TO::3310::newFromDevice ($dev->{key}/$dev->{ipno}): $rc->{error}");
        return undef;
     }
     $report = $rc->{report};
  }
  $obj->{info}{disk_map} = $report->{"info.disk_map"};
  $obj->{info}{top_disk} = $report->{"info.top_disk"};

  Agent::3310->getPortWWNS($dev, $report);

  my ($x, $ports, $cnt);
  if (($dev->{type} eq "3510") ||($dev->{type} eq "3511") ) {
    for ($x=0; $x <= 20; $x++) {
       next if (!exists $report->{"port.$x.id"});
       my $wwn = $report->{"port.$x.wwn"} ;
       $obj->{portInfo}[$x]{PortWWN}      = $wwn;
       $obj->{portInfo}[$x]{LocalPortWWN} = $wwn;
       $obj->{portInfo}[$x]{Slot}         = substr($wwn,2,1);
       $obj->{portInfo}[$x]{id}           = $report->{"port.$x.id"};
       $to->addSyn($wwn, "$type:$key:$x");
       $obj->{info}{port_cnt} = $x + 1;
    }
  }

  if($key =~ /SUN.3310jbod\.(.*)/){
     $obj->{info}{wwns} = $1;
  }elsif($key =~ /SUN.3120jbod\.(.*)/){
     $obj->{info}{wwns} = $1;
  }elsif($key =~ /SUN.3310\.(.*)/){
     $obj->{info}{wwns} = $1;
  }elsif($key =~ /SUN.3320\.(.*)/){
     $obj->{info}{wwns} = $1;
  }elsif($key =~ /SUN.3120\.(.*)/){
     $obj->{info}{wwns} = $1;
  }
  $obj->{info}{disk_cnt} = $report->{"info.total_physical_drives"};
  bless($obj, uc("TO::$type"));

  $to->addSyn($key, "$type:$key");
  $to->addSyn($dev->{wwn}, "$type:$key") if ($dev->{wwn});

  delete $storages->{$org_name} if ($org_name);
  $storages->{"$type:$key"} = $obj;
  return $obj if ($exists); 

  $obj->{port}= [];
  
  return $obj;
}

sub display_rows {
  my($class, $obj) = @_;

  my $rows = int($obj->{info}{top_disk} / 16);
  my ($display_rows, $r, $row_list, $d);

  if (!$obj->{info}{disk_map}) {
    my($row_list, $x);
    for ($x=0; $x < $rows; $x++) {
      $row_list .= "$x/";
    }
    chop($row_list) if ($row_list);
    return ($rows, $row_list);
  }

  my @MAP  = split(/,/, $obj->{info}{disk_map});

  for ($r=0; $r <= $rows; $r++) {
      my ($found);
      for ($d=0; $d <= 11; $d++) {
          my $ix = $r*16 + $d;
          if ($MAP[$ix]) {
             $found=1; last;
          }
      }
      if ($found) {
        $display_rows++;
        $row_list .= "$r/";
      }
  }
  chop($row_list) if ($row_list);
  return ($display_rows, $row_list);
}


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 ($portInfo, $otherInfo, $port);
  my $other;

  my($disk, $diskInfo, $d, $c, $map, @MAP);
  if ($node->{info}{disk_map}) {
    $map = 1;
    @MAP = split(/,/, $node->{info}{disk_map});
  }

  my (@C, @D, $x);
  foreach my $el (keys %$Comp) {
    if ($el =~ /^channel\.(\d+)/) {
      my $p = $1;
      my $val =$Comp->{$el};
      if ($val->[0] > $C[$p][0]) {
         $C[$p] = [$val->[0], $val->[1]];
      }

    } elsif ($el =~ /^components.disk\.(\d+)/) {
      my $p = $1;
      my $val =$Comp->{$el};
      if ($val->[0] > $D[$p][0]) {
         $D[$p] = [$val->[0], $val->[1]];
      }
    }
    my $val =$Comp->{$el};
    $Comp->summ($el, \$other, \$otherInfo);
  }
  shift(@C);  # first channel(port) is 1
  foreach my $e (@C) {
    $port .= "$e->[0],";
    $portInfo .= "$e->[1],";
  }
  my $rows = int($node->{info}{top_disk} / 16);
  my ($r, $d);
  for ($r=0; $r <= $rows; $r++) {
     my ($disk0, $diskInfo0, $found);
     for ($d=0; $d <= 11; $d++) {
        my $ix = $r*16 + $d;
        my $e = $D[$ix];
        if ($MAP[$ix]) {
          $disk0 .= "$e->[0],";
          $diskInfo0 .= "[Encl-$r disk-$d] $e->[1],";
          $found=1;
        } else {
          $disk0 .= "-1,";
          $diskInfo0 .= "[Encl-$r disk-$d],";
        }
     }
     if ($found) {
       $disk .= $disk0;
       $diskInfo .= $diskInfo0;
     }
  }

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




sub iconLayout {
  my($obj) = @_;
  my ($cat, $label2, $ses);
  my ($rows, $dd) =  TO::3310->display_rows($obj);
  my $cnt = 12;

  my $ports = $obj->{info}{port_cnt} || 1;

  $cat = "a,3310,$ports/  ,$cnt,$dd,_,,E0D0F0/3310.gif";

  $label2 = $obj->{info}{LGroup};
  $ses = 1;

  return ($cat, $label2, $ses);
}

# "a,$t3,2/12,-$dt,$dd,LMPVA,Loop/Midplane/Power/Volumes/Alerts,D0D0F0/t3pg.gif";

1;
