package Logic::Subnet;

use strict;
use Logic;
use Agent::T3;
use Logic::SWITCH;
use Agent::MCDATA;

# host => 'hosttosearch',  SUB1..6 => 'subnet', prefixT => 'use hostname as prefix', 
# prefix => 'custom prefix', monitor_on => 'turn-on monitoring'
# timeout => 6

sub addToConfig {
  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;

   if ($q->{SUB1} !~ /\d+\.\d+\.\d+/) {
       $err= Error->error('subnet.101');
       return ($err, []);
   } else {
       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 (!$host) {
           $data = &get_snmpdata($q);

       } else {
          my $sub;
          for ($x=1; $x <= 6; $x++) {
             $sub .= "&SUB$x=" . $q->{"SUB$x"};
          }
	  print "Running on Host: $q->{host}. This could take up to 5 minutes. There will be no screen output during this time.<br>";
          my $rc = Util::Http->getCommand($host, "Logic::Subnet::snmpdata&REM=1$sub&timeout=$q->{timeout}", 500);
          if (substr($rc,0,2) ne "OK") {
	      if($rc) {
                 my $err = Error->error(2, $rc);
	      } else {
	         my $err = Error->error(3) ;
	      }
              return($err, []);
          } else {
              my @A = split(/\n/, substr($rc,2));
              $data = \@A;
          }
       }
       my $short = Util->shortHostname($host || $renv->{hostname});

       foreach my $line (@$data) {
          my($class, $type, $ip, $wwn, $key, $wwn2, $ctrl, $devname, $label) = split(/\|/, $line) ;
          if ($class eq "ERR") {
             $err_text .= "ERR: $type, \n";
             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 {
               $devs->[$new_dev]{name} = "$type-$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}     = $q->{host};
             $devs->[$new_dev]{active}   = ($monitor_on ? "Y":"N");
             #$dev->[$new_dev]{datahost} = $datahost;
             push(@nodes, $devs->[$new_dev]);
             print " $type:$ip added. \n";

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

sub get_snmpdata {
  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);
  for ($x=1; $x <= 6; $x++) {
     $sub = $q->{"SUB$x"};
     next if ($sub !~ /^\d+\./);
     foreach my $x (0,20,40,60,80,100,120,140,160,180,200,220,240) {
	if($x == 240){
           print "Probing ports $sub.$x  .. 255 \n" if (!$remote);
        }
        else{
           print "Probing ports $sub.$x  .. " . ($x+19) . " \n" if (!$remote);
        }
        $out = Logic::Subnet->snmpget($sub, "public 1.1.0", $x, $x+19, $q->{timeout});
        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");
        }
     }
  }
  if ($remote) {
     print "OK" . join("\n", @L);
  } else {
     return \@L;
  }
}


sub snmpget {
  my($func , $ip, $f, $start, $end, $sleep_time) = @_;
  my($err, @out, $l, $x, $ipno, $comm, $cnt, $ret);
  if (!-d "/tmp") {
     mkdir "/tmp" , 0777;
  }

  $sleep_time = 5 if (!$sleep_time);
  $sleep_time = 2 if ($sleep_time == 1);

  my($prog) = System->get_home() . "/snmp/bin/snmpget";
  for ($x = $start; $x <= $end; $x++) {
     unlink("/tmp/ras_snmp_$x");
  }
  for ($x = $start; $x <= $end; $x++) {
     last if ($x > 255);
     $ipno = "$ip." . $x;
     $comm = "$prog -t " . ($sleep_time-1) ." -r 0 $ipno $f > /tmp/snmp_$x 2>&1";
     system("$comm&");
  }
  sleep($sleep_time);
  $cnt= 0;
  for ($x = $start; $x <= $end; $x++) {
     last if ($x > 255);
     open(O, "/tmp/snmp_$x");
     $ret = <O>; close(O);
     chop($ret);
     $ipno = "$ip." . $x;

     if ($ret !~ /No Response/) {
        my(@b) = split(/\s*=\s*/, $ret);
        if (lc($b[1]) =~ /brocade/) {
           my $wwn = Util->snmpWWN($ipno);
	   my $mymodel = Agent::BROCADE->getModel($ipno); 

#           push(@out, "switch.brocade|brocade|$ipno|$wwn|$wwn|$wwn");
           push(@out, "switch.brocade|brocade|$ipno|$wwn|$wwn|$wwn|||$mymodel");
	} elsif (lc($b[1]) =~ /mcdata/) {
	   if($ret =~ /Connectivity Manager/){
	      # This is the Management pc, skip it
	      next;
	   }
	   my $mymodel = Agent::MCDATA->getModel($ipno);
	   my $wwn = Util->snmpWWN($ipno);
           push(@out, "switch.mcdata|mcdata|$ipno|$wwn|$wwn|$wwn|||$mymodel");

        } elsif (lc($b[1]) =~ /switch/ || lc($b[1]) =~ /sanbox/) {
           my($wwn, $type, $label) = Logic::SWITCH->find_wwn($ipno);
           push(@out, "switch.$type|$type|$ipno|$wwn|$wwn|$wwn|||$label") if ($type);

	}elsif (lc($b[1]) =~ /t3/) {
           my $class = "storage.t3";
           my $type  = "t3";
           my($key, $wwn ,$wwn2, $ctrl, $name, $label) =  Agent::T3->getWWN($ipno);
           if (!$key) {
              push(@out, "ERR|Invalid Key for T3 $ipno, cannot add !");
           } else {
              push(@out, "$class|$type|$ipno|$wwn|$key|$wwn2|$ctrl|$name|$label");
           }
        }
     }
  }
  return \@out;
}


1;



