#!/usr/bin/perl -w
#
# mocpro_level2.pl

# mocness tow data file processing routine - level 2
# 23June97/srg 
# Further modified August 11, 1997 rcg
# Modified Nov. 4, 1997 Change to level 2.  rcg
# Modified Nov. 10, 1997. Change sorting of tow names to be case insensitive. 
#	Also added a space after # in output lines.  rcg
# November 14, 1997 rcg Change output message to say displayed by.
# November 30, 1997. rcg  Add date test for string month in day field.
# December 3, 1998. rcg Redirect messages to DMO mail, rather than as comments,
#	add cruiseid and year to incoming parameters and cruiseid
#	to next level script. 
# December 4, 1998.  Add local year as expected passed parameter;  Look 
#	at eventlog for old cruises to get day and month values.
# December 8, 1998.  Add test if comment field is defined.
# December 17, 1998. Add host name or number to mailed error message.
# January 28, 1999.  Fix misspelling of MAILFILE (was TEMPFILE) in
#	message subroutine.  rcg
# Febrary 18, 1999.  Display tow values with underscores (_) changed
#	to minus signs.  rcg
# March 24, 1999.  Add station and standard station fields from eventlog
#	file when available.  rcg
# April 14, 1999.  Make Ashjian enhancements the real one.  Change script
#	 location back to /data/rgroman/ctd_mocness.  rcg
# May 3, 1999.  Add line to flush output buffer.  rcg
# May 20, 1999.  Check for tow number with the word Tow in it and try
#	to isolate the real tow number, e.g. cruise EN263.  rcg
# May 29, 1999.  Need to work on tow vs cast/comment test.  There
#	are problems with non-numeric values.  Not repaired yet.  
#	Need to repair comparison in numalpha to test correctly for
#	non-numeric characters.  rcg
# June 4, 1999.  Use list rather than listgb program.  rcg
# June 8, 1999.  Add additional code to handle tow & cast numbers with
#	non-numeric characters. rcg
# June 9, 1999.  V2.10 Add defined test to comment in case it isn't.  rcg
# July 12, 1999. V2.11 Update sendmessage routine to send mail and output
#	message.  RCG
# January 28, 2000.  V2.12 Fix Y2K computation.  rcg
# October 3, 2001.  V2.12so - Set up for Southern Ocean.  Based on GB version
#	Naming convention for tow and 
# December 24, 2001.  V2.13ZG. Modified for ZooGene data.  rcg
# March 6, 2003. V2.14ZG  Modified March 6, 2003.  Change location of
# 	script file and file names to be /data1/zoogene_data/mocness from
# 	/data1/zoogene/Scripts/mocness.  rcg
# July 10, 2006.  V2.15CM  Modify for CMarZ data
# Dec. 12, 2011. V2.16BC Modified for BCO-DMO data. Scripts 
#       on dmoserv2 at /data/Scripts/ctd_mocness  mda + rcg
#

$version="V2.16BC/Dec. 12, 2011";

# Looks at all the MOC files in the /data2/gbdata and other places
# processing those with a "moc" subdir and then
# the files found with the file type specified at run-time.
#
# sets up info required for mocpro_level2.pl based
# on results of files lists and initial header data
# in the data files
#
# Passed parameter
#	$ARGV[0] = data directory for these data
#	$ARGV[1] = MOC1, or MOC10 or MOC.25 specifying which MOCNESS
#			data type to view
#	$ARGV[2] = file type to process, e.g. pro, tab, raw  (note:
#			the code will have to change to accommodate
#			other than pro format.)
#	$ARGV[3] = cruiseid
#	$ARGV[4] = local four digit year

$| = 1;

#some definitions
$error="&x";
$warning="#";
$script_loc="/data/Scripts/ctd_mocness";   # script location dir
$script_name="mocpro_level3.pl";           # next script name
$i_am_level=2;
$fieldnames_level[0]="/data/Scripts/ctd_mocness/fieldnames_level0";
$fieldnames_level[1]="/data/Scripts/ctd_mocness/fieldnames_level1";
$fieldnames_level[2]="/data/Scripts/ctd_mocness/fieldnames_level2";
$fieldnames_level[3]="/data/Scripts/ctd_mocness/fieldnames_level3";
$moc1patterns="/data/Scripts/ctd_mocness/moc1patterns";
$moc10patterns="/data/Scripts/ctd_mocness/moc10patterns";
$mocpoint25patterns="/data/Scripts/ctd_mocness/mocpoint25patterns";

($moc_dir, $datatype, $filetype, $cruiseid, $year) = @ARGV;
$filetypeuc=uc $filetype;

print STDOUT ("#Displayed by $0, $version\n",
	"#  For $moc_dir, $datatype, $filetype, $cruiseid, $year\n");

$datatype = uc $datatype;
if ($datatype eq "MOC10" ) {
	open PATTERN, $moc10patterns or 
		die "# $0 could not read $moc10patterns patterns file, $!";
	@pattern=<PATTERN>;
	chomp @pattern;
#	print STDOUT "#**debug, numb patterns=$#pattern, patterns=@pattern\n";
	close PATTERN;
}elsif ($datatype eq "MOC1" ) {
	open PATTERN, $moc1patterns or 
		die "# $0 could not read $moc1patterns patterns file, $!";
	@pattern=<PATTERN>;
	chomp @pattern;
#	print STDOUT "#**debug, numb patterns=$#pattern, patterns=@pattern\n";
	close PATTERN;
}elsif ($datatype eq "MOC.25" ) {
	open PATTERN, $mocpoint25patterns or 
		die "# $0 could not read $mocpoint25patterns patterns file, $!";
	@pattern=<PATTERN>;
	chomp @pattern;
#	print STDOUT "#**debug, numb patterns=$#pattern, patterns=@pattern\n";
	close PATTERN;
} else {
	print STDOUT "# $0 cannot recognize datatype=$datatype";
	exit 0;
}
if ($filetype eq "pro" ) {
#	yes, we can handle this format
}
else {
	print STDOUT "# $0 cannot handle filetype=$filetype";
	exit 0;
}

$index=-1;
$data=();
@datafile = <$moc_dir/*.$filetype>;    # get the data files
push @datafile, <$moc_dir/*.$filetypeuc>;
foreach $checkfile (@datafile) {
#	print STDOUT "\n#**debug, checkfile: $checkfile\n";
	foreach $pattern (@pattern) {
		$_=$checkfile;

		if ( m/$pattern/ ) {
			$datafile=$checkfile;
#			print STDOUT ("#**debug: fileokay, pattern=$pattern, ",
#				" datafile=$datafile\n");
			goto FILEOKAY;
		}
	}
#	print STDOUT ("#**debug, skip this file, not of interest\n");
	next;	#skip this file, not of interest
	
FILEOKAY:open(PROFILE, $datafile) or 
		die "# Could not open data file $datafile, $!";
#	print STDOUT "\n**debug, opening file=$datafile\n";
	$index++;
	$tow[$index]="nd";
	$month_local[$index]=0;
	$day_local[$index]=0;
	$datafile[$index]=$datafile;
READDATA:while(<PROFILE>) {
		s/^\% /%/;
		$record=$_;
		chomp;
		if( m/Tow/ )  {
#			print STDOUT ("#***debug, tow record=$_\n");
			@towline = split;
			$tow[$index] = $towline[1];
#			print STDOUT ("#***debug, tow[$index]=$tow[$index]\n");
		}
		elsif( m/Date:/ ) {
			if ((index $record, "/" ) > 0) {
				@dateline = split;
				$dateline[1]=~s/ //g;
				@cruisedate = 
					split(/\//,$dateline[1]);
#				print STDOUT ("#**debug, file=$datafile ",
#					"dateline[1]=$dateline[1] ",
#					"cruisedate[0]=$cruisedate[0] ",
#					"cruisedate[1]=$cruisedate[1]\n"); 
				$month_local[$index] = $cruisedate[1];
				$day_local[$index]=$cruisedate[0];
			}
			else {
				@cruisedate = split /\s/, $record;
				$month_local[$index]=$cruisedate[$#cruisedate-2];
				$day_local[$index]=$cruisedate[$#cruisedate-1];
				$test=&monthtonum ($day_local[$index]);
				if (  $test <= 12 and $test >= 1) {
					$day_local[$index]=$month_local[$index];
					$month_local[$index]=$test;
				}
			}
			if (! defined $month_local[$index]) {
				$month_local[$index]=0;
			}
			if (! defined $day_local[$index]) {
				$day_local[$index]=0;
			}
			if ($month_local[$index] < 1 or 
					$month_local[$index] > 12 ) {
				$message0="Bad month value of " . 
					$month_local[$index];
				$message1="Data file=$datafile";
				&sendmessage ($warning, $message0, $message1);
			}
			if ($day_local[$index] < 1 or 
					$day_local[$index] > 31 ) {
				$message0="Bad day value of $day_local[$index]";
				$message1="Data file=$datafile";
				&sendmessage ($warning, $message0, $message1);
			}
			last READDATA;
		}
		elsif ( m/^\d\d.*/ )  {
			$tow[$index] = $datafile;
			$tow[$index] =~ s/^.*-(\d{1,})\.$filetype$/$1/;
			&get_some_data_from_eventlog (
				$cruiseid, $datatype, $tow[$index], 
				$day_local[$index],
				$month_local[$index]);
			
			unless (defined $month_local[$index]) {
				$month_local[$index] = "nd"; }
			unless (defined $day_local[$index] ) {
				$day_local[$index]= "nd"; }
			last READDATA;
		}
		else {
			$message0= "Unexpected data format found" .
				" in file " . $datafile[$index];
			$message1= "Record read=" . $_;
			&sendmessage ($warning, $message0, $message1);
			last READDATA;
		}
	}
	close(PROFILE);
	$i=$index;		
	$string= "(" . $script_loc . "/" . $script_name . " " . 
		$datatype . " " . $filetype . " " . $datafile[$i] . 
		" " . $cruiseid . ")";
	$townumb = $tow[$i];
	$townumb =~ s/_/-/g;
#	print STDOUT ("#***debug, townumb=$townumb\n");

	if ( $townumb =~ m/[-Mm]/ ) { $townumb =~ s/.*-(\d+[a-zA-Z]*)$/$1/; }
	if ( $townumb =~ m/Tow/ ) { $townumb =~ s/.*-Tow(\d+[a-zA-Z]*)$/$1/; }
	&get_some_data_from_eventlog ($cruiseid, $datatype, $townumb, 
		$station,$station_std);
	unless (defined $station) {$station='nd'}
	unless (defined $station_std) {$station_std='nd'}
	print STDERR (" $0 : station=$station, station_std=$station_std\n");
#	$station=~ s/.*(\w+).*/$1/;
#	$station_std=~ s/.*(\w+).*/$1/;
	$dataline = $townumb . "\t" . $day_local[$i] . "\t" . 
		$month_local[$i] . "\t" . $station . "\t" . 
		$station_std . "\t" . $string . "\n";
	push @data, $dataline;       
}
#print STDOUT "#**debug, length of fieldnames_level=$#fieldnames_level\n";

for ($i=$i_am_level; $i <= $#fieldnames_level; $i++) {
#	print STDOUT "#**debug,  fieldnames_level[$i]=$fieldnames_level[$i]\n";
	open FIELDNAMES, $fieldnames_level[$i] or 
		die "# Could not get field names from $fieldnames_level[$i], $!";
		@fieldnames=<FIELDNAMES>;
		close FIELDNAMES;
		chomp (@fieldnames);
		foreach $variable (@fieldnames) {
			print STDOUT "$variable\t" unless (index $variable, "#") >= 0;
		}
	print STDOUT "\n";
}
#print STDOUT ("#**debug, last index=$index\n#\t",
#	"Lengths of tow, day_local, month_local=$#tow, ",
#	"$#day_local, $#month_local\n");
	
foreach $line (sort numalpha @data) {
	print STDOUT $line;
}

undef $error;
undef $warning;
exit 0;

#---------------------------------------------------------------------------

sub sendmessage {

#Send a message to the user.
#The message sent will be in the strings $_[1] and $_[2]
#The prefix string is in $_[0]

my ( @args, $mailfile, $message0, $message1, $prefix, $who);
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst);

$prefix=$_[0];
$message0=$_[1];
$message1=$_[2];
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
if ($year >= 100 and $year <1000) { $year = $year + 1900; }
$mon++;
if ($mon < 10) { $mon = "0" . $mon; }
if ($mday < 10) {$mday = "0" . $mday; }
if ($hour < 10) { $hour = "0" . $hour; }
if ($min < 10) { $min = "0" . $min; }
if ($sec < 10) { $sec = "0" . $sec; }
$mailfile=">/tmp/sendmess" . $year . $yday . $hour . $min . $sec . ".tmp";

if ( open TEMPFILE, $mailfile) {
	if ( exists $ENV{'REMOTE_HOST'} ) {$who=$ENV{'REMOTE_HOST'} ; }
	elsif (exists $ENV{'REMOTE_ADDR'} ) {$who=$ENV{'REMOTE_ADDR'} ; }
	else {$who="not available"; }
	print TEMPFILE ("Message from $0\n");
	print TEMPFILE (" Date of message: $year/$mon/$mday $hour:$min\n");
	print TEMPFILE (" From: $who\n");
	print TEMPFILE (" $message0\n");
	print TEMPFILE (" $message1\n");
	close TEMPFILE;
	`/usr/bin/mail -w dmo\@globec.whoi.edu <$mailfile`;
	unlink $mailfile;
}
print STDOUT ($prefix,"Message from $0\n");
print STDOUT ($prefix," Date of message: $year/$mon/$mday $hour:$min\n");
print STDOUT ($prefix," $message0\n");
print STDOUT ($prefix," $message1\n");

return;
}

#---------------------------------------------------------------------------

sub numalpha {
my ($a1, $b1, @rest, $type);
($a1, @rest)=split /\t/, $a;
($b1, @rest)=split /\t/, $b;
$a1=lc $a1;
$b1=lc $b1;
#print STDOUT "#**debug, a1=$a1, b1=$b1, ";
$type="n";
$_=$a1;
if ( m/.*^\D.*/ ) {	$type="l";}
$_=$b1;
if ( m/.*^\D.*/ ) {	$type="l";}
#print STDOUT " type=$type\n"; 
if ($type eq "n") {
	if ( ($a1 <=> $b1) == -1) {
		return -1;
	}
	elsif( ($a1 <=> $b1) == 0) {
		return 0;
	}
	else {
		return 1;
	}
}
else {
	if ( ($a1 cmp $b1) == -1) {
		return -1;
	}
	elsif( ($a1 cmp $b1) == 0) {
		return 0;
	}
	else {
		return 1;
	}
}
}

#---------------------------------------------------------------------------

sub monthtonum {

#Given the text string for the month, $_[0], , return the month number, 1 - 12

my %month = (
	jan => 1,
	january => 1,
	feb => 2,
	february => 2,
	mar => 3,
	march => 3,
	apr => 4,
	april => 4,
	may => 5,
	jun => 6,
	june => 6,
	jul => 7,
	july => 7,
	aug => 8,
	august => 8,
	sep => 9,
	sept => 9,
	september => 9,
	"oct" => 10,
	october => 10,
	nov => 11,
	november => 11,
	dec => 12,
	december => 12,
	);
if (defined $month{lc $_[0]})  {
	return $month{lc $_[0]};
}
else {
	return "nd";
}

}



#---------------------------------------------------------------------------

sub get_some_data_from_eventlog {

# Use the event log object to get at day and month for old format data
# Arguments passed are:
#	$_[0] = cruiseid
#	$_[1] = datatype
#	$_[2] = tow

# Values returned are:
#	$_[3] = day_local
#	$_[4] = month_local
#	$_[5] = station

my ($cast, $cruiseid, $datatype, $day, $input, 
	$listgb, $listgb_options, 
	$message0, $message1, $month, $object_spec, 
	$station, $tow );

$cruiseid = $_[0];
$datatype = uc $_[1];
$tow = $_[2];
#print STDOUT ("#**debug, cruiseid=$cruiseid, datatype=$datatype, tow=$tow\n");
$listgb = "/home/bco/dbase-v2/bin/list ";
$listgb_options = "-c -n -b -t ";
#$object_spec = "\"/CMarZ/eventlog_rhb(instrument=$datatype," .
#		"cast,day_local,month_local,station)\"";

$object_spec = "\"/CMarZ/eventlogs(cruiseid=$cruiseid,inst=$datatype," .
		"cast,day_local,month_local,station)\"";

#print STDOUT ("\n#***debug, object_spec=$object_spec\n");

$input = $listgb . $listgb_options . $object_spec . "|";

#print STDOUT ("\n#***debug, input=$input\n");

$_[3] = "nd";
$_[4] = "nd";
$_[5] = "nd";
unless ( open EVENTLOG, $input) {
	$message0="Could not open eventlog to get day and month";
	$message1="open=$input";
	&sendmessage ($warning, $message0, $message1);
	return;
}
# Search for correct tow number and use day and month values
#print STDOUT ("\n#***debug, Just before while statement to read the eventlog\n");

my $data_record;
while ($data_record =<EVENTLOG>) {
	($cast, $day, $month, $station) = split /\t/, $data_record;
#	print STDOUT ("\n#***debug, station=$station\n");
	if (defined $cast  and ($cast=~m/\d+/) and ($tow=~m/\d+/) and
		( not $cast=~m/[a-zA-Z]+/) and ( not $tow=~m/[a-zA-Z]+/) ) {
		if ( $cast == $tow ) {
			$_[3] = $day;
			$_[4] = $month;
			$_[5] = $station;
			last;
		}
	}
	elsif (defined $cast) {
		if ( $cast =~ m/$tow/ ) {
			$_[3] = $day;
			$_[4] = $month;
			$_[5] = $station;
			last;
		}
	}
}
close EVENTLOG;
return;
}


