#!/var/opt/STORtools/bin/perl

require  "subroutines.pm";
&st_globals();

$PROGNAME = "sfdmp";
####################################################################
#
# MAIN
# Usage : $PROGNAME -name {<driver-inst>} {-file}
#         where driver-inst is the instance # of an FCA driver
# Ex: $PROGNAME -name socal0
# look for the specified socal, sf instance number
# photon array (I dont know what this means)
# get all entries for the specified driver instance from the rawdump output
#
####################################################################

&check_root_access( $PROGNAME );
# process the inputs
&proc_cli;

# make a names list
&get_rawdump;
&make_name_list;

foreach $loop_name (@name_list) {
	#print "\n=============  Loop: $loop_name ==============\n\n";
	&proc_lparr; 
	#print "\n=========== End of Loop: $loop_name ========== \n";
}

# End of MAIN


####################################################################
#    SUBROUTINES
#
####################################################################
################################################################
# process this loop array
# if the loop is in this loop array, then print out 
# the ha and disk information.
# search all loops in the rawdump for the given box/loop
#
# input:
#   [AB]    loop id
# 
################################################################
sub proc_lparr {
	$prevloop = 0;
	$fndloop = "FALSE";

	$srch = ${loop_name};
	print "This is the search string = $srch\n" if ($debug);
	$prevloop = &get_next_looparr($prevloop);


	while ($prevloop <= $#goldraw) {
		$found = "FALSE";
		foreach $line (@looparr) {
			if ($line =~ /${srch}/) {
				$found = TRUE;
				last;
			}
		}
		if ($found eq "TRUE") {
			&pr_a5k;
			&pr_ha;
			&pr_ses;
			&pr_disks;
			$fndloop = "TRUE";
		}
		if ($prevloop == $#goldraw) {
			last;
		}
		$prevloop = &get_next_looparr($prevloop);
	}

	if ($fndloop eq "FALSE") {
		print "\tLoop Not Found.\n";
	}
}

################################################################
# print the HA information for this looparr
################################################################
sub pr_a5k {
	undef @this_alist;

	print "\nEnclosures Connected to this loop:\n";
	foreach $line (@looparr) {
		if ($line =~ /^(\S+),([AB])[01]/) {
			$tmp = $1;
			$this_lpid = $2;
			$a1 = grep {/$tmp/} @this_alist;
			if (! $a1) {
				push @this_alist, $tmp;
				print "\t${tmp}\t Loop ${this_lpid}\n";
			}
		}
	}
}

################################################################
# print the HA information for this looparr
################################################################
sub pr_ha {
	undef @loopha;
	# format for ha section
	#       0  1  2  3   4
	@pfh = (8, 8, 6, 50, 8);
	print "\nHA/s\n";     
	foreach $line (@looparr) {
		if ($line =~ /\*HA\*/) {
			push @loopha, $line;
		}
	}

	foreach $line (@loopha) {
		@thisha = split (' ', $line);

		($portnum) = $thisha[10] =~ /:(\d)/;
		if($portnum eq "0") {
			$haport = "port0";
		} else {
			$haport = "port1";
		}

		printf("%-$pfh[0]s%-$pfh[1]s%-$pfh[2]s%-$pfh[3]s\n\n",
		$thisha[8], $haport, $thisha[9], $thisha[10]);
	}
}

################################################################
# print the ses/enclosure information for this looparr
################################################################
sub pr_ses {
	# print format for disks in loop 
	#        0   1   2  3  4  5
	@pfa = (18, 15, 18, 7, 5, 8);


    	$display=0;
	
	foreach $line (@looparr) {
		if ($line =~ /^(\S+),[AB][01]/) {
		   if($display==0)
		   {
		      # there is some data to be printed so go
		      # ahead and print heading
		         printf("%-$pfa[0]s%-$pfa[1]s%-$pfa[2]s%-$pfa[3]s%-$pfa[4]s%-$pfa[5]s%-s\n\n",
	            "Name", "Enclosure","WWN", "ALPA", "ID", "ses", "Physical Path");
		     $display=1;
		   }
			(@line) = split(' ', $line);
   printf("%-$pfa[0]s%-$pfa[1]s%-$pfa[2]s%-$pfa[3]s%-$pfa[4]s%-$pfa[5]s%-s\n",
	$line[0], $line[3], $line[1], $line[4], $line[6], $line[8], $line[10]);
		}
	}
	print "\n";
}

################################################################
# print the disk information for this looparr
################################################################
sub pr_disks {
	# print format for disks in loop 
	#        0   1   2  3  4  5
	@pfa = (18, 15, 18, 7, 5, 8);

  printf("%-$pfa[0]s%-$pfa[1]s%-$pfa[2]s%-$pfa[3]s%-$pfa[4]s%-$pfa[5]s%-s\n\n",
	"Name", "Disks","WWN", "ALPA", "ID", "ssd", "Physical Path");
    
	foreach $line (@looparr) {
		if ($line =~ /\S*,[fr]/) {
			(@line) = split(' ', $line);
     printf("%-$pfa[0]s%-$pfa[1]s%-$pfa[2]s%-$pfa[3]s%-$pfa[4]s%-$pfa[5]s%-s\n",
	$line[0], $line[3], $line[1], $line[4], $line[6], $line[8], $line[10]);
		}
	}
}

##############################################################
# now parse the raw data by loop
# rawdump output is sorted by loop
# the next blank line indicates the end of the loop
# everything in between are the items in the loop
# find a block and put it into an array.  
# inputs:
#   bginsrch    start the search at this line
# outputs:
#   lastha      last ha line searched
##############################################################
sub get_next_looparr {
	($index) = @_;
	if (($index < 0) || ($index > $#goldraw)) {
		die "ERROR 4000";
	}

	undef @looparr;

	# Skip any initial blank lines
	while (($index <= $#goldraw) && ($goldraw[$index] =~ /^\s*\n$/)) {
		$index++;
	}

	for ($i = $index; $i <= $#goldraw; $i++) {
		if ($goldraw[$i] =~ /^\s*\n*$/) {
			# Loop information in the rawdump output are
			# separated by blank lines.
			# Stop storing when we find a blank line.
			last;
		}
		# store this 'rawdump' output line in the array 'looparr'
		push @looparr, $goldraw[$i];
	}

	if (@looparr) {
		return ($i);
	} else {
		return $#goldraw;
	}
}

####################################################################
# Get rawdump data and put it into an array
#
####################################################################
sub get_rawdump {
	# if live, then call rawdump and put output into an array
	#  save the output into a file in case we need to pass it on

	if ($live eq "TRUE") {
		print "probing system... (please allow 30 seconds for each A5K Series Enclosure)\n";
		@goldraw = `$BINDIR/rawdump`;
		open (TMPFILE, ">${TMP_RAW}") or
		die "Unable to open temporary file: /var/tmp/current_a5k_rd\n";
		print TMPFILE @goldraw;
		close(TMPFILE);
	} elsif ($rawfile eq "TRUE") {
		open (TMPFILE, "${TMP_RAW}");
		while ($line=<TMPFILE>) {
			push @goldraw, $line;
		}
		close(TMPFILE);
	} else {

		# if not live, extract the rawdump information from the snapshot

		$golden_log = &get_golden_snapshot();
		if ($golden_log) {
			open(GOLDRAW, "${GOLD_PATH}/$golden_log") or
		die "Unable to open golden logfile: ${GOLD_PATH}/$golden_log\n";
		} else {
			die "Unable to find Golden logfile.\n";
		}

		$found_section = "FALSE";

		while ($line=<GOLDRAW>) {
			if ($line =~ /^RAWDUMP:/) {
				$found_section = "TRUE";
				next;
			}
			next if ($found_section eq "FALSE");
			last if ($line =~ /^============/);
			push @goldraw, $line;
		}
	}

	#       0   1   2   3  4  5  6  7  8  9  10
	@fw = (19, 17, 17, 14, 5, 5, 3, 4, 8, 8, 100);

	print @goldraw if ($debugrd);

	print "\n==========end of array===========\n" if ($debugrd);
}

################################################################
# make a list of names
# if name is an input, then single item in list
# else (all), then go discover all of the FC devices/drivers 
# connected to this system using the rawdump output
################################################################
sub make_name_list {
	undef @name_list;
	undef @fca_drvr_list;	# socal, ifp, usoc, qlc
	undef @fca_xport_list;	# sf, fp
	undef @a5k_list;	# List of all A5k's
	undef @t300_list;	# List of all T300's

	my     ($tmp, $a1, $b1, $c1);	# Local variables

	# make a list of all of the online FC drivers on this system

	foreach $line (@goldraw) {
		(@line) = split(' ', $line);

		if ($line[8] =~ /^socal|^usoc|^qlc|^ifp/) {
			$a1 = grep {/$line[8]/} @fca_drvr_list;
			if (! $a1) {
				push @fca_drvr_list, $line[8];
			}
		}

		if ($line[9] =~ /^sf|^fp/) {
			$b1 = grep {/$line[9]/} @fca_xport_list;
			if (! $b1) {
				push @fca_xport_list, $line[9];
			}
		}

		if ($line =~ /^(\S+),[AB][01]/) {
			$tmp = $1;
			$a1 = grep {/$tmp/} @a5k_list;
			if (! $a1) {
				push @a5k_list, $tmp;
			}
		}

		if ($line =~ /^T300,/) {
			# If it is a T300, take the target digit from "cxtxdx"
			$tmp = $1 if ($line[3] =~ /^c\d+t(\d+)d\d+/);
			$tmp = "T300-" . $tmp;
			$c1 = grep {/$tmp/} @t300_list;
			if (! $c1) {
				push @t300_list, $tmp;
			}
		}
	}

	if ($all eq "FALSE") {
		$a1 = grep {/$in_key/} @fca_drvr_list;
		$b1 = grep {/$in_key/} @fca_xport_list;
		if (! (($a1) | ($b1))) {
			print "fca driver/transport : $in_key not present.\n";
			exit;
		} else {
			push @name_list, $in_key;
		}
	} else {
		if (($fca_xport_list[0] !~ /\S+/) ||
				($fca_drvr_list[0] !~ /\S+/)) {
			print "No online FC Adapter on this system.\n";
			exit;
		} else {
			@name_list = @fca_xport_list;
		}
	}
}

sub proc_cli {

	# print the usage
	$usage[0] = "$PROGNAME help |[-live | -file]|-name <name> | -all \n";
	$usage[1] = "help - display usage\n";
	$usage[2] = "live - use the current data (loop disruptive)\n";
	$usage[3] = "name - name of component\n";
	$usage[4] = "all  - process all supported FC drivers and transports \n";
	$usage[5] = "file - use file (${TMP_RAW}) for input\n";

	if ($ARGV < 0) {
		die @usage;
	}
	# init vars
	my $do_something = "FALSE";
	$live = "FALSE";
	$all = "TRUE";
	$in_key = "";

	$arg = shift @ARGV;
	while($arg) {
		if ($arg =~ /-name/) {
			$in_key = shift @ARGV;
			$do_something = "TRUE";
			$all = "FALSE";
		} elsif ($arg =~ /-live/) {
			if ($rawfile eq "TRUE") {
				die @usage;
			}
			$live = "TRUE";
			$do_something = "TRUE";
		} elsif ($arg =~ /[?|h]/i) {
			die @usage;
		} elsif ($arg =~ /-file/i) {
			if ($live eq "TRUE") {
				die @usage;
			}
			$rawfile = "TRUE";
		} elsif ($arg =~ /-debug/i) {
			$debug = "TRUE";
		} elsif ($arg =~ /-rd/i) {
			$debugrd = "TRUE";
		} elsif ($arg =~ /-all/) {
			if ($in_key ne "") {
				die @usage;
			}
			$all = "TRUE";
			$do_something = "TRUE";
		} else {
			die "\nUndefined Option!\n\n @usage";
		}
		$arg = shift @ARGV;
	}
	if ($in_key eq "") {
		$all = "TRUE";
	}
}
