package Linktest::HBA;
use strict;
use Linktest;
use Linktest::Node;
use base 'Linktest::Node';


sub portTest {
   my($node_a, $node_b) = @_;
   if($node_a->{path} eq ""){
     $node_a->prompt('no_valid_path');
     exit(-2);
     return(0);
   }
   if($node_a->{path} =~ /JNI/){
     # This is a JNI card, no Port test available 
     return(0);
   }

   if( ($node_a->{path} =~ /emlx/) || ($node_a->{path} =~ /10df/) || ($node_a->{path} =~ /lpfs/) || ($node_a->{path} =~ /lpfc/) ){
     # This is a Emulex card, Port test is available 
     return(1);
   }
   
   if($node_a->{path} =~ /ifp/){
     # This is an IFP card, no Port test available 
     return(0);
   }
   # Check to see if this is a qlc port that automatically loops the port if no
   # connection is present.
   my $topo = $node_a->{_topo_node};

   my $ports = $topo->portInfo();

   foreach my $port (@$ports){
     if($port->{path} =~ /$node_a->{path}/){
        # This is the node we are working with
	if($port->{CardType} =~ /0x4083/){
	   # Check to see if this is port 0
	   # If it is, this isn't a testable port
	   if($node_a->{path} =~ /qlc\@4/){
	      # This port automatically loops unconnected ports
	      $node_a->prompt('qlc_auto_loopback' );
	      exit(-1);
	      return(0);
	   }
	}
	last;
     }
   }
   return(1);
}

sub class {'hba'}

sub type2 {"HB"}

sub prompt_info {
  my($node) = @_;
  return ($node->{path}, $node->{port});
}

sub node_isolation {
  my($node_a, $node_b, $failed_node) = @_;
  
  Linktest->debug_header( $node_a, $node_b, "hba_node_isolation" );

  my ($answer, $status, $out);

  if ( $node_a->{path} =~ /ifp/) {
    $node_a->prompt('remove_hba_cable' );
    $answer = Linktest->ask_continue();
    if ( $answer ne "n" ) {
      $out = start_diagnostic( $node_a, "E" );
    } else {
      $node_a->prompt('restore_hba_cable' );
      Linktest->premature_exit();
    }
    if ( $out->{rc} == 0 ) {
      # the test passed, the HBA node is OK
      # test the next node, could be a cable problem
      $node_a->prompt('restore_hba_cable' );
      $node_a->prompt('functional_hba' );
      $answer = Linktest->ask_continue();
      if ( $answer ne "n" ) {
        return $Linktest::SUCCESS;
      } else {
        Linktest->premature_exit();
      }
    } else {
      $node_a->prompt('restore_hba_cable' );
      $node_a->prompt('suspect_hba' );
      return $Linktest::FOUND_SUSPECT_FRU;
    }
  }

  $node_a->prompt('remove_hba_cable' );
  $node_a->prompt('insert_hba_loopback' );
  $answer = Linktest->ask_continue();
  if ( $answer ne "n" ) {
    $out = start_diagnostic( $node_a, "E" );
  } else {
    $node_a->prompt('remove_hba_loopback' );
    $node_a->prompt('restore_hba_cable' );
    Linktest->premature_exit();
  }
  if ( $out->{rc} == 0 ) {
    # the test passed with a loopback, the HBA node is OK
    # test the next node, could be a cable problem
    $node_a->prompt('remove_hba_loopback' );
    $node_a->prompt('restore_hba_cable' );
    $node_a->prompt('functional_hba' );
    return $Linktest::SUCCESS;
  }
 if ( $node_a->{path} =~ /socal/ ) {

    $node_a->prompt('remove_hba_loopback' );
    $node_a->prompt('replace_hba_gbic' );
    $node_a->prompt('insert_hba_loopback' );
    $answer = Linktest->ask_continue();
    if ( $answer ne "n" ) {
      $out = start_diagnostic( $node_a, "E" );
    } else {
      $node_a->prompt('remove_hba_loopback' );
      $node_a->prompt('restore_hba_gbic' );
      $node_a->prompt('restore_hba_cable' );
      Linktest->premature_exit();
    }
    if ( $out->{rc} == 0 ) {
      # the test passed with a new GBIC. The GBIC is the suspect.
      $node_a->prompt('remove_hba_loopback' );
      $node_a->prompt('restore_hba_cable' );
      $node_a->prompt('suspect_hba_gbic' );
      Linktest->retest_msg();
      return $Linktest::FOUND_SUSPECT_FRU;
    } else {
      Linktest->premature_exit();
    }

  }

  $node_a->prompt('remove_hba_loopback' );
  if ( $node_a->{path} =~ /socal/ ) {
    $node_a->prompt('restore_hba_gbic' );
  }
  $node_a->prompt('restore_hba_cable' );
  $node_a->prompt('suspect_hba' );
  return $Linktest::FOUND_SUSPECT_FRU;

}


sub start_diagnostic {
  my($node, $mode)  = @_;
  my ($test, $options, $estimated_time, $sparcv9);
  

  my($verbose, $wb_patterns, $option_user_pattern,$option_pattern_type) = $node->diag_defaults();
  if(($node->{path} =~ /qlc/) || ($node->{path} =~ /jfca/) || ($node->{path} =~ /emlx/) || ($node->{path} =~ /10df/) || ($node->{path} =~ /lpfs/) || ($node->{path} =~ /lpfc/)){
      if($node->{path} =~ /jfca/){
         # This is a JNI card
		$test = "jnitest";
		$options = "$verbose -q -o ". '"' . "dev=$node->{path}|selectpattern=$wb_patterns" . $option_user_pattern . '"';

      }elsif(($node->{path} =~ /emlx/) || ($node->{path} =~ /10df/) || ($node->{path} =~ /lpfs/) || ($node->{path} =~ /lpfc/)) {
         # This is a Emulex card
         $test = "emlxtest";
         if ( $mode eq "E" ) {
           $options = "$verbose -o " . '"' . "dev=$node->{path}|selftest=Disable|ilb=Disable|elb=Enable|iterations=100|selectpattern=$wb_patterns" . $option_user_pattern . '"';
         } elsif ( $mode eq "I" ) {
           $options = "$verbose -o " . '"' . "dev=$node->{path}|selftest=Disable|ilb=Enable|elb=Disable|iterations=10|selectpattern=$wb_patterns" . $option_user_pattern . '"';
         } elsif ( $mode eq "C" ) {
           $options = "$verbose -o " . '"' . "dev=$node->{path}|selftest=Enable|ilb=Enable|elb=Disable|iterations=10000|selectpattern=$wb_patterns" . $option_user_pattern . '"';
         } else {
           Linktest->tbd_msg();
           Linktest->premature_exit();
         }

      }else{
         $test = "qlctest";
         if ( $mode eq "E" ) {
           $options = "$verbose -q -i1 -f -o " . '"' . "dev=$node->{path}|run_connect=Yes|selftest=Disable|checksum=Disable|ilb_10=Disable|ilb=Disable|elb=Enable|iterations=100|xcnt=65536|selectpattern=$wb_patterns" . $option_user_pattern . '"';
         } elsif ( $mode eq "I" ) {
           $options = "$verbose -q -i1 -f -o " . '"' . "dev=$node->{path}|run_connect=Yes|selftest=Disable|checksum=Disable|ilb_10=Enable|ilb=Enable|iterations=10|xcnt=65536|selectpattern=$wb_patterns" . $option_user_pattern . '"';
         } elsif ( $mode eq "C" ) {
           $options = "$verbose -q -i1 -f -o " . '"' . "dev=$node->{path}|run_connect=Yes|selftest=Enable|checksum=Enable|ilb_10=Enable|ilb=Enable|elb=Disable|iterations=10000|xcnt=10|selectpattern=$wb_patterns" . $option_user_pattern . '"';
         } else {
           Linktest->tbd_msg();
           Linktest->premature_exit();
         }
      }
      if ($option_pattern_type eq "user") {
        $estimated_time = 1;
      } elsif ($option_pattern_type eq "critical") {
        $estimated_time = 1;
      } else {
        $estimated_time = 2;
      }
    } elsif ( $node->{path} =~ /ifp/ ) {
      $sparcv9 = ($node->{bitMode} == 64) ? "sparcv9/" : "";
      $test = "ifptest";
      $options = "$verbose -q -i1 -f -o " . '"' . "dev=$node->{path}|mbox=e|fwrevcheck=e|checksum=e|modrevcheck=e" . '"';
      $estimated_time = 1;
    } elsif ( $node->{path} =~ /socal/ ) {
      $test = "socaltest";
      if ( $mode eq "E" ) {
        $options = "$verbose -q -i1 -f -o " . '"' . "dev=$node->{path}|ilb=disable|elb=disable|lbf=enable|iterations=100|xcnt=65536|selectpattern=$wb_patterns" . $option_user_pattern . '"';
      } elsif ( $mode eq "I" ) {
        $options = "$verbose -q -i1 -f -o " . '"' . "dev=$node->{path}|ilb=disable|elb=enable|lbf=disable|selectpattern=$wb_patterns" . $option_user_pattern . '"';
      } elsif ( $mode eq "C" ) {
        $options = "$verbose -q -i1 -f -o " . '"' . "dev=$node->{path}|ilb=enable|elb=disable|lbf=disable|selectpattern=$wb_patterns" . $option_user_pattern . '"';
      } else {
        Linktest->tbd_msg();
        Linktest->premature_exit();
      }
      if ($option_pattern_type eq "user") {
        $estimated_time = 1;
      } elsif ($option_pattern_type eq "critical") {
        $estimated_time = 1;
      } else {
        $estimated_time = 4;
      }
    }
   
    return $node->run_diagnostic($test, $sparcv9, $options, $estimated_time);
}


1;


  

