package Logic::SWITCH;
use Logic;
use Logic::Subnet;
use Agent::BROCADE;
use strict;

#  host => , ip => , name => , 
#  return ($err_object, $nodes_list);
#  $q->{host} = ''         : local
#  $q->{host} = <hostname> : slave

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

  while (1) {
     if ($q->{name} eq "") {
        $err = Error->error(102);
        last;
     } elsif (!$q->{ip}) {
        $err = Error->error("103");
        last;
     } else {
        my($renv, $devs, $hosts,$notifs) = PDM::ConfigFile->read();
        my(%F);
        foreach my $d (@$devs) {
          if ($d->{class} =~ /^switch/ ) {
             $F{$d->{wwn}} = 1;
          }
        }
        ($err, $nodes) = $class->add($q, $devs, \%F);
        if (!$err && $nodes) {

           Logic->clearSlave($q->{host}, $hosts);
           if (!PDM::ConfigFile->write( $renv, $devs, $hosts,$notifs)) {
              $err = Error->error('10');
           }
        }
     }
     last;
  }
  return ($err, $nodes);
}

sub addFromFile {

   my($class, $q) = @_;
   my(@nodes,$err, $err_text, $x);
   my $host       = $q->{host};
   my $monitor_on = $q->{monitor_on};
   my $datahost   = $q->{datahost};
   $q->{prefix} =~ s/\./_/g;
   my(@DATA, %F, $adding, $found);
   my($renv, $devs, $hosts,$notifs) = PDM::ConfigFile->read();
   my $new_dev = $#$devs ;

   my $cnt=1;
   foreach my $d (@$devs) 
   {
     if ($d->{class} =~ /switch/ || $d->{class} =~ /storage.t3/) 
     {
        $F{$d->{key}} = $cnt;
     }
     $cnt++;
   }

   if (!$q->{select_host} || $q->{select_host} eq "local")
   {
      # Get info from this host
      my $dd =  &get_infoFromFile($q);
      push(@DATA, @$dd);
   } 

   foreach my $host0 (@$hosts) {
      if (!$q->{select_host} || $q->{select_host} eq $host0->{hostname}) {
        # Get info from remote host

        my $rc = Util::Http->getCommand($q->{select_host}, "Logic::SWITCH::infoFromFile&REM=1", 300);
        if (substr($rc,0,2) ne "OK" || !$rc)  {
           my $err = Error->error(1, "$rc $Util::Http::ERROR");
           return($err, []);
        } else {
           my @A = split(/\n/, substr($rc,2));
           my $x;
           for ($x=0; $x <= $#A; $x++) {
               push(@DATA, "$A[$x]|$host0->{hostname}");
           }
        }
      }
   }
   my $short = Util->shortHostname($host || $renv->{hostname});
   foreach my $line (@DATA) 
   {
      my($class, $type, $ip, $wwn, $key, $wwn2, $ctrl, $devname,$label, $host1) = split(/\|/, $line) ;
      if(($type eq "") || ($class eq ""))
      {
         next;
      }
      elsif ($class eq "ERR") 
      {
         $err_text .= "ERR: $type, ";
         next;
      }
      #print "$class, $type, $ip, $wwn, $key, $wwn2 <br>";

      if (!$F{$key}) 
      {
         $F{$key} = 1;
         $adding = 1;
         $found++;
         $new_dev++;
         my($ip1,$ip2,$ip3, $ip4) = split(/\./, $ip);
         $devs->[$new_dev]{_name}    = "device" . $new_dev;
         $devs->[$new_dev]{type}     = $type;
         $devs->[$new_dev]{class}    = $class;
         my $n1 = $devname || "$ip3-$ip4";
         if ($q->{prefixT}) 
	 {
            $devs->[$new_dev]{name}     = $short ."-" . 
                ($devname || sprintf("%3.3d", $ip4)) ;
         } 
	 elsif ($q->{prefix}) 
	 {
            $devs->[$new_dev]{name}     = $q->{prefix} . "-$n1";
         } 
	 else {
            my $tt = substr($type,0,2);
            $devs->[$new_dev]{name} = "$tt-$n1";
         }
         $devs->[$new_dev]{ctrl_model}= $ctrl if ($ctrl);
         $devs->[$new_dev]{userLabel}= $label if ($label);
         $devs->[$new_dev]{ip}       = $ip;
         $devs->[$new_dev]{ipno}     = $ip;
         $devs->[$new_dev]{wwn}      = $wwn;
         $devs->[$new_dev]{wwn2}     = $wwn2;
         $devs->[$new_dev]{key}      = $key;

         $devs->[$new_dev]{host}     = $host1;
	    
         $devs->[$new_dev]{active}   = "Y";
         print " $type:$ip added. \n<br>";
         push(@nodes, $devs->[$new_dev]);

      } 
      else 
      {
         print " $type:$ip already exists.\n<br>";
      }
   }
   if ($adding) 
   {
      foreach my $h (@$hosts) 
      { 
         $h->{last_push} = undef;
      }
      PDM::ConfigFile->write( $renv, $devs, $hosts,$notifs);
   }
  
   return ($err, \@nodes, $err_text);

}

sub get_infoFromFile{

  my($q, $post, $util) = @_;
  my(%T, @a, $loc, $ip, $out);
  my(%F, $d, $adding, $found, $l );
  my(@NEW);
  my($xx, $sub, $remote, $x);

   $remote   = $q->{REM};

   my(@L);
   my $file = "/etc/fcswitch.conf";

   if (!open(OO, $file)) 
   {
      my $err = Error->error(104, $!);
      return ($err, undef);
   }
   my ($adding, @nodes, $info);
   while ($l = <OO>) 
   {
      chomp($l);
      next if ($l !~ /^\d+/);
      my @a = split(/\s+/, $l);

      # @a[0] has the ip value
      my @b = split(/\./, $a[0]);


      $out = Logic::Subnet->snmpget("${b[0]}" . ".$b[1]". ".$b[2]", "public 1.1.0", $b[3], $b[3], 1);

      foreach my $node (@$out) {
           my($class, $type, $ip, $wwn, $key, $wwn2, $ctrl, $name, $label) = split(/\|/, $node);
           push(@L, "$class|$type|$ip|$wwn|$key|$wwn2|$ctrl|$name|$label");
      }

   }
   close(OO);


  if ($remote) {
     print "OK\n" . join("\n", @L);
  } else {
     return \@L;
  }

}

sub add {
  my($class, $q, $devs, $F) = @_;
  my (@nodes, $err);
  my($ipno, $python, $msg, $adding);
  my $host = $q->{host};
  my $ip   = $q->{ip};
  my $name = $q->{name};


  if (!($ipno = Util->testIp($ip))) {
      my $err = Error->error("switch.101", $ip);
      return ($err, []);
  }
  my($wwn, $type, $label) = $class->find_wwn($ipno);
  if (!$wwn) {
      my $err = Error->error("switch.102", $ipno);
      return ($err, []);
  
  } elsif (!$F->{$wwn} ) {
      $F->{$wwn} = 1;
      my($new_dev) = $#$devs  + 1;


      $devs->[$new_dev]{_name}    = "device" . $new_dev;
      $devs->[$new_dev]{type}     = $type;
      $devs->[$new_dev]{class}    = "switch.$type";
      $devs->[$new_dev]{name}     = $name || "S" . $ip;
      $devs->[$new_dev]{ip}       = $ip;
      $devs->[$new_dev]{password} = $q->{password};
      $devs->[$new_dev]{wwn}      = $wwn;
      $devs->[$new_dev]{userLabel}= $label;
      $devs->[$new_dev]{key}      = $wwn;
      $devs->[$new_dev]{ipno}     = $ipno;

      my($renv, $devs1, $hosts1,$notifs1) = PDM::ConfigFile->read();

      $devs->[$new_dev]{host}     = $q->{host};

      $devs->[$new_dev]{active}   = "Y";
      $F->{$wwn} = 1;
      push(@nodes, $devs->[$new_dev]);

  } else {
      my $err = Error->error("switch.103");
      return ($err, []);
  }
  return (undef, \@nodes);  #  if ($type ne "switch");  look for more switch if its a sunswitch

#
#     LOOK FOR MORE SWITCHES, may not be used anymore
#     
  my($err,$com) = Util->run_command( System->get_home() .
                      "/bin/sanbox port_status $ip all", "raidutil.txt", 10);
  foreach my $l (@$com) {
     if ($l =~ /T_Port\s+Linked-to:/) {
        my($l0) = $l;
        $l0 =~ /Port:\s+(\d+)/;
        my($port) = $1;
        $l =~ /Linked-to: ([0-9a-f]+)\s+IP:\s+([0-9\.]+)\s+FC:\s+(\w+)/;
        my($wwn2, $ipno2, $fc2) = ($1,$2,$3);
        if ($wwn2) {
           if (!$F->{$wwn2} ) {
              $F->{$wwn2} = 1;
              my($new_dev) = $#$devs  + 1;

              my($wwn, $type, $label) = $class->find_wwn($ipno2);
              $devs->[$new_dev]{_name}    = "device" . $new_dev;
              $devs->[$new_dev]{type}     = 'switch';
              $devs->[$new_dev]{class}    = 'switch.switch';
              if ($ipno2 =~ /\d+\.\d+\.\d+\.(\d+)/) {
                 $devs->[$new_dev]{name}     = "csw-" . $1;
              } else {
                 $devs->[$new_dev]{name}     = "csw-$fc2";
              }
              $devs->[$new_dev]{ip}       = $ipno2;
              $devs->[$new_dev]{wwn}      = $wwn;
              $devs->[$new_dev]{fc}       = $fc2;
              $devs->[$new_dev]{port}     = $port;
              $devs->[$new_dev]{primary}  = $ip;
              $devs->[$new_dev]{wwn}      = $wwn;
              $devs->[$new_dev]{key}      = $wwn;
              $devs->[$new_dev]{ipno}     = $ipno2;
              $devs->[$new_dev]{host}     = $host;
              $devs->[$new_dev]{active}   = "Y";
              $F->{$ipno2} = 1;
              push(@nodes, $devs->[$new_dev]);
            }
        }
     } # end if T port
  } #end foreach

  return ($err, \@nodes);
}

sub find_wwn {
  my($class, $ip) = @_;
  my($wwn, $type);

  my($err,$com) = Util->run_command(
         System->get_home() . "/bin/sanbox version $ip", "raidutil.txt", 10);
  "@$com" =~ /WWN:\s+(\w+)/;
  $wwn = lc($1);

  if ("@$com" =~ /No response/) {
     my $wwn = Agent::BROCADE->getWWN($ip); 
     my $mymodel = Agent::BROCADE->getModel($ip); 

     return ($wwn, 'brocade', $mymodel);


  } else {
     my($err,$com) = Util->run_command(
         System->get_home() . "/bin/sanbox chassis_status $ip", "raidutil.txt", 10);
     if ("@$com" =~ /SANbox-8/i) {
       return ($wwn, 'switch2', 'Switch1');
     } elsif ("@$com" =~ /SANbox1-8/i) {
       return ($wwn, 'switch2', 'Switch1');
     } elsif ("@$com" =~ /SANbox-16/i) {
       return ($wwn, 'switch2', 'Switch1');
     } elsif ("@$com" =~ /SANbox1-16/i) {
       return ($wwn, 'switch2', 'Switch1');
     } elsif ("@$com" =~ /SANBox2/i) {
       return ($wwn, 'switch2','Switch2');
     } else {
       return ($wwn, 'switch', 'Switch1');
     }
  }
}
#ccad$ snmpwalk 172.20.67.167 public sysDescr
#system.sysDescr.0 = Brocade Switch
#ccad$ snmpwalk 172.20.67.198  public sysDescr
#system.sysDescr.0 = Fibre Channel Switch
#ccad$ snmpwalk 172.20.67.195  public sysDescr
#system.sysDescr.0 = SANbox1-16
#ccad$ snmpwalk 172.20.67.183  public sysDescr
#system.sysDescr.0 = QLogic SANBox2 FC Switch


1;
