package Service::Array;

use Net::FTP;
use Net::Telnet;
use Net::Ping;
use System;
use strict;

use vars qw($host_file $syslog_conf $target_syslog $array_user $array_name  $array_prompt $array_password $SP_ADDRESS $log_file $tnet $log_path $ERR);


  $host_file      = "/etc/hosts";
  $syslog_conf    = "/opt/array_conf/etc/syslog.conf";
  $target_syslog  = "/etc/syslog.conf";
  $log_path       = "/var/opt/SUNWstade/log/"; 

  $array_prompt   = '/\S*:\/:<\d+>/'; #[ARRAYNAME]:/:<command#>
  $array_user     = "root";

  $SP_ADDRESS = "192.168.0.2";  # may be good idea to get from /etc/hosts file

#
#  RETURN ERROR_CODE
#  - ONLY RUNS IF PASSWORD is currently BLANK
#  - UPDATE ARRAY AND SET PASSWORD TO SAVED PASSWORD.
#
sub add {
  my($class, $ip) = @_;

  $array_name     = $ip;

  $array_password = System->getPassword("array");
  $array_name     = &getArrayName($ip);

  if (!&pingArray() ) {
     return "Error: ping $ip failed, Can not find the array";
  }

  if (&badPassword("")) {
    
    print "$array_name: Password is already set.\n";
    return undef;
  }
  #
  # GETS HERE ONLY IS PASSWORD IS BLANK
  #
  if(!$class->openArrayConnection($array_name, "")){
    return "Error: Cannot Login to array. If this is a new array, a blank password is needed";
  }

  if (&configureArray($array_name) ) {
    return "Error: Failed to modify the array configurations";
  }

  if (&changePassword() ) {
    return "Error: Cannot change password. If this a new array, a blank password is needed";
  }
  print "$array_name: Password is now set.\n";


  &closeArrayConnection;
  my $rc;
  if ($rc = &syslogTransfer() ) {
    return "Error: Failed to open ftp connection with the array(rc=$rc)";
  }

# Remove for now since 6120.sh fails and takes way to long.
# PatchPRO should be updating the /web directory on the array anyways.
#
#  if (&updateArrayPatch) {
#    return "Error: Failed to modify the array configurations";
#  }

  return undef;
}

sub getArrayName {
  my($ip) = @_;
  my($l, $found);

  open(O, "/etc/hosts");
  while ($l = <O>) {
     my($ip0, $name, $rest) = split(/\s+/, $l);
     if ($ip0 eq $ip) {
       $found = $name; last;
     }
  }
  close(O);
  return $found;
}


#return 1 on success , 0 Fail
sub pingArray
{
  my $ping;
  my $status;
  
  $ping = Net::Ping->new("icmp");
  $status = $ping->ping($array_name);
  $ping->close;

  return($status);
}

# Open ftp section to transfer /opt/array_conf/etc/syslog.conf
# Return 0 if OK and 1 Fail

sub syslogTransfer
{
  my $ftp;

  if(-e "$syslog_conf")  {
      # wait up to 3 minutes
      unless ($ftp = Net::FTP->new($array_name, Timeout => 200 )) { 
         return 1;
      }
  
      unless ($ftp->login($array_user, $array_password)) {
         return 2;
      }
  
      unless ($ftp->put($syslog_conf, $target_syslog)) {
         return 3;
      }
      $ftp->quit;
  } else {
    return 4;
  }

  return 0;
}


# return 0 on sucess , 1 on Fail
sub badPassword {
  my($pass) = @_;

  $tnet = Net::Telnet->new(
             errmode => "return",
             Timeout   => 10,
             Prompt    => $array_prompt,
             );

  $tnet->open(Host => $array_name);
  if ($tnet->errmsg()) {
     return 1;
  } 

  $tnet->login($array_user, $pass);
  if ($tnet->errmsg()) {
     return 1;
  } 
  $tnet->close; 
  return 0;
}

# return ('Error_message', "Info");

sub boot_w {
  my($class, $name, $password) = @_;
  $array_name     = $name;
  $array_password = $password;
  
  if (!&pingArray() ) {
     return ("Cannot Ping $name");
  }
  if (&badPassword($password) ) { 
  # Based on the discussions on bug 6314863, Blank should not be 
  # an indication of trying default password. We will use "#DEFAULT#"
  # as an indication. Xuefeng Yao 08/31/2005
    if ($password ne "#DEFAULT#") {
      return ("Cannot login to array");

    } else { # for "#DEFAULT#", try the array_password
       my $pass2 = System->getPassword("array");
       if (&badPassword($pass2)) {
          return ("Cannot login to array");
       } else {
          $array_password = $pass2;
       }
    }
  }

  my $tnet = $class->openArrayConnection($array_name, $array_password);
  return ("Cannot open connection to $array_name") if (!$tnet);

  my $confirm_prompt = ".*? \[N\]\: ";
  my @l	      = $tnet->cmd(String => "boot -w", Prompt => $confirm_prompt, Timeout => 5);
  my @confirm = $tnet->cmd(String => "Y",	Prompt => ".*",            Timeout => 5);

  #my @l = $tnet->cmd(String => "fru stat", Prompt => $array_prompt);

  return (undef, "@l");

}



#
# Open telnet section to change password
# Return 1 if OK or 0 is not
#

sub changePassword
{

  my @l  = $tnet->cmd(String => "passwd", Prompt => '/\:/');
  my @l2 = $tnet->cmd(String => "",     Prompt => '/\:/');
  my @l3 = $tnet->cmd(String => $array_password,     Prompt => '/\:/');
  my @l4 = $tnet->cmd(String => $array_password,     Prompt => $array_prompt);

  return 1 if ("@l4" =~ /sorry/);
  return 0;

}
  
#
# Configure the array
# Return 0 if OK and 1 if not
#
sub configureArray {
  my($array_name) = @_;

  my @l = $tnet->cmd(String => "set timezone GMT", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "ntp server $SP_ADDRESS", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "ntp poll unicast", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "ntp interval 60", Prompt => $array_prompt);

#######   setting setup parameters
 
  my @l = $tnet->cmd(String => "set bootmode auto", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "set netmask 255.255.255.0", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "set gateway $SP_ADDRESS", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "set tftphost $SP_ADDRESS", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "set tftpfile  /var/crash/$array_name/", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "set hostname $array_name", Prompt => $array_prompt);

###### setting system parametsers

  my @l = $tnet->cmd(String => "sys mp_support mpxio", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "sys disk_scrubber on", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "sys ondg befit", Prompt => $array_prompt);
  my @l = $tnet->cmd(String => "sys fc_topology auto", Prompt => $array_prompt);

  return 1 if (&cleanFileSystem);
  return 0;
}


# return 0 if successfull 
sub cleanFileSystem {

  my @l = $tnet->cmd(String => "ls -1", Prompt => $array_prompt);

  foreach my $file (@l) {
       if ($file =~ /[t4|lpc]\S+.bin/i) {
           my @l = $tnet->cmd(String => "rm $file", Prompt => $array_prompt);
       }
  } 
  return 0;
}

# return 0 if successful 
sub updateArrayPatch {

my $patchlocation = "/var/sadm/swimages";
my $result;
my $T4_patch = `ls $patchlocation|grep 115179`; 

if($T4_patch =~/115179-\d+/) {
    $patchlocation = "$patchlocation/$T4_patch";
    chomp($patchlocation);

#### here document for adding path to T4

$result = `$patchlocation/6120.sh <<EOF
$array_name
$patchlocation

root
$array_password
`;
} else {
       return 1;
}
return 0;
}

#Returns $tnet if successful , undef otherwise

sub openArrayConnection {
  my($class, $array_name, $pass) = @_;
  $ERR = undef;
  $tnet = Net::Telnet->new(
             errmode   => "return",
             Timeout   => 20,
             Prompt    => $array_prompt,
             );

  $tnet->open(Host => $array_name);
  if ($tnet->errmsg()) {
     $ERR = $tnet->errmsg();
     return 0;
  }

  $tnet->login($array_user, $pass);
  if ($tnet->errmsg()) {
     $ERR = $tnet->errmsg();
     return 0;
  }

  return $tnet;
}

sub closeArrayConnection {

  $tnet->close;

}

sub openLogFile {

my $LOGFILE = "$log_path/add_array.$array_name";

my $result = open(LOG,">>$LOGFILE");
        if(!(defined($result))) {
           return 1;
        }

return 0;
}

sub printLog {

my ($msg) = @_;

   print LOG "$msg \n";

}

1;
