#!/usr/local/bin/perl -w
#
# ctd_jk_level1.pl

# John Klinck CTD data file processing routine - level 1

$version = "V1.00/March 28, 2003";

# March 28, 20023Robert C. Groman
# Copyright 2003 Woods Hole Oceanographic Institution

# Looks at all the CTD files specified in subdirectory $ARGV[1],
# processing those with the specified patterns specified at run-time
# via the configuration file specified as $ARGV[0].

# Sets up info required for the next level based
# on results of files founde matrix (vector) being read.
#
# Passed parameter
#	$ARGV[0] = configuration file
#	$ARGV[1] = subdirectory of files to process

# Asuumptions
#	1. Program code must match the number and type of arguments specified in
# the level 1 field names from the configuration file.
#	2. Field name key words are specified as ID_<field_name> within
# the configuration file.  For example, cast is ID_cast.  Use these key words
# to search for the value within the CTD event file.
#	3. Assumes <ctd_event_file> is located below the ship name
# directory, one level higher than the subdirectory passed.  We get 
# all the date, time, position information from here.
#	4. Assumes cast number is part of the file name of the data file as
# ctd001.dat where 001 is the cast number that matches to the cast number within
# the ctdevent.dat file.

unshift (@INC, "/data/rgroman/perllib");
        require ('sendmessage.pl');
        require ('make_log_entry.pl');
        require ('read_configuration_file.pl');
        require ('bob_setup.pl');
        require ('bob_unsetup.pl');
        require ('valid_number.pl');

&bob_setup();

$i_am_level=1;
$max_levels = 10;

unless ( defined $ARGV[0] ) {
	print STDOUT ("$error Displayed by $0, $version\n",
		"$error Required configuration file not specified.\n");
	exit;
}

unless (defined $ARGV[0] ) {
	&make_log_entry("Configuration file not passed along");
	&sendmessage($error, "Required configuration file name not passed along",
		"Cannot continue");
	exit;
}
$configuration_file = $ARGV[0];

@required = (
	'field_names_level_0', 'field_names_level_1', 'field_names_level_2', 
	'cast_pattern',
	'ctd_event_file', 'data_file_type', 'data_file_pattern', 
	'next_script', 'next_configuration_file'

);

&read_configuration_file($configuration_file);

$debug = 'no';
if (exists $config_param{'debug'} and defined $config_param{'debug'} ) {
	if ($config_param{'debug'} =~ m/^y/i or 
	   $config_param{'debug'} =~ m/^1/ or 
	   $config_param{'debug'} =~ m/^t/i) {;
		$debug = "yes";
	}
	elsif ($config_param{'debug'} =~ m/^keep/i ) {
		$debug = "keep";
	}
}

&make_log_entry (">>>>>>>Begin Program=$0",
	"Date of run=$date\tVersion=$version",
	"Configuration file=$configuration_file");


print STDOUT ("#Displayed by $0, $version\n");
unless (defined $ARGV[1] ) {
	&make_log_entry("Data file directory not passed along");
	&sendmessage($error, "Required data file directory not passed along",
		"Cannot continue");
	exit;
}
$data_subdirectory = $ARGV[1];
print STDOUT ("#  Data subdirectory is $data_subdirectory\n");

$status = ' ';
foreach (@required) {
	unless (exists $config_param{$_} and defined $config_param{$_} ) {
		$status = $status . ' ' . $_;
	}
}

unless ($status eq ' ') {
	&make_log_entry(
		"Required configuration parameters not defined=$status");
	&sendmessage($error, "Required configuration parameters $status",
		"not defined.");
	exit;
}

#Determine number of levels
for ($i=0; $i<=$max_levels; $i++) {
	$last_fieldname_level = $i-1;
	unless (defined $config_param{"field_names_level_$i"} and
		exists$config_param{"field_names_level_$i"} ) {last} ;
}

if ($last_fieldname_level >= ($max_levels-1) ) {
	&make_log_entry("Maximum number of levels exceeded=$max_levels");
	&sendmessage($error, "Maximum number of levels exceeded",
		"at $max_levels   Cannot continue");
	exit;
}

$data_file_type = $config_param{'data_file_type'}; 
$data_file_type_uc = uc $config_param{'data_file_type'}; 
$data_file_pattern = $config_param{'data_file_pattern'}; 
$data_file_pattern_uc = uc $config_param{'data_file_pattern'};

$ctd_event_file = $data_subdirectory . '/' . $config_param{'ctd_event_file'};
    
$cast_pattern = $config_param{'cast_pattern'};

$next_script = $config_param{'next_script'};
$next_config_file = $config_param{'next_configuration_file'};

# Output field names

for ($i=$i_am_level; $i <= $last_fieldname_level; $i=$i+1) {
	unless (defined $config_param{"field_names_level_$i"} and
			exists $config_param{"field_names_level_$i"} ) {last;}
	@fieldnames = split /,/, $config_param{"field_names_level_$i"};
	if ($i == $i_am_level) {
		@current_field_names = @fieldnames;
	}
	foreach $variable (@fieldnames) {
		$variable =~ s/^\s+//;
		$variable =~ s/\s+$//;
		print STDOUT ("$variable\t");
	}
	print STDOUT ("\n");
}

print STDOUT ("#***debug, data_file_pattern=$data_file_pattern, ",
	"data_file_type=$data_file_type\n") if $debug eq 'yes';

print STDOUT ("#***debug, data_subdirectory=$data_subdirectory\n")
	if $debug eq 'yes';
@datafiles = <$data_subdirectory/$data_file_pattern\.$data_file_type>;
@datafiles_uc = <$data_subdirectory/$data_file_pattern_uc\.$data_file_type_uc>;
push @datafiles, @datafiles_uc;

print STDOUT ("#***debug, datafiles[0]=$datafiles[0]\n") if $debug eq 'yes';

if ($#datafiles < 0 ) {
	&make_log_entry("Expected data files in directory=$data_subdirectory",
		"With header type=$data_file_type");
	&sendmessage($error,"No data files of type $data_file_type found in",
		"directory $data_subdirectory");
	exit;
}

#Get CTD event data from separate file
$status = &read_ctd_event_file($ctd_event_file);

unless ($status eq 'okay' ) {
	&make_log_entry("Could not get CTD event file data from file=$ctd_event_file",
		"Status=$status");
	&sendmessage($error,"Could not get CTD event data from $ctd_event_file",
		"Status was $status");
	exit;
}

foreach $file (sort @datafiles)   { 
	if ($file eq '.' or $file eq '..') {next;}
	$datafile = $file;
	print STDOUT ("#***debug, datafile=$datafile\n") if $debug eq 'yes';
	$cast_value = $file;
	$cast_value =~ s/$cast_pattern/$1/;
	if ($cast_value eq $file) {
		&make_log_entry("Could not find cast value from file=$file");
		$cast_value = 'nd';
	}
	&make_log_entry("Working on file=$file", "Cast value=$cast_value")
		if $debug eq 'yes';
	undef %fieldname;
	foreach $fieldname (@current_field_names) {		
		if ($fieldname eq "" or $fieldname eq '>' ) {next}
		$key = 'ID_' . $fieldname;
		unless (exists $config_param{$key} and defined $config_param{$key} ) {
			&make_log_entry("Key word not defined for=$key");
			&sendmessage($error,
			"Key word not defined for key $key",
			"Cannot continue.  Contact the DMO.");
			exit;
		}
		
		$key_equiv = $config_param{$key};
		$key_equiv =~ s/%/ /g;
		$value = &find_key_value_in_records ($cast_value, $key_equiv);
		print STDOUT ("#***debug, cast value=$cast_value, key=$key, ",
			"key_equiv=$key_equiv, value=$value\n")
			if $debug eq 'yes';

		$fieldname{$fieldname} = $value;
	}
	
	foreach $fieldname (@current_field_names) {
		if ($fieldname eq "" or $fieldname eq ">" ) {next;}
		unless (exists $fieldname{$fieldname} and defined $fieldname{$fieldname} ) {
			&make_log_entry("Value not defined for fieldname=$fieldname");
			&sendmessage($warning,
				"Value not defined for fieldname $fieldname",
				"Will use nd value.");
			print STDOUT ("nd\t");
		}
		else {		
			print STDOUT ($fieldname{$fieldname},"\t");
		}
	}

	print STDOUT ("($next_script $next_config_file $datafile)\n");
}		

&make_log_entry ("<<<<<<<End Program=$0");

undef $warning;
undef $date;
&bob_unsetup();

exit 0;

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

sub read_ctd_event_file {

# Open CTD event file, _[0], and create the hash table event_file_field_names
# where
#		$event_file_field_names{'<field name>'} = <column position>
# 
# and the array @array containing all the records from the file.
# Example format of the head is as follows:
#	Ygrid         I  kilometers
#	Total depth   I  meters


my ($ctd_event_file, $i, $numb_values, $record, $type, $units);

$ctd_event_file = $_[0];

unless (open EVENT, $ctd_event_file) {
	$status = $!;
	&make_log_entry("Could not open CTD event file=$ctd_event_file",
		"Status=$!");
	return $status;
}

$numb_values = <EVENT>;
chomp $numb_values;
$numb_values =~ s/\s//g;

unless (&valid_number($numb_values) )  {
	print STDOUT ("#***debug, valid_number($numb_values), =",
		&valid_number($numb_values), "\n") if $debug eq 'yes';
	&make_log_entry("First CTD event record not legal value=$numb_values");
	return "Illegal number of field names was $numb_values";
}
for ($i=1; $i<=$numb_values; $i++) {
	$record = <EVENT>;
	chomp $record;
#	$field_name = $record;
#	$field_name =~ s/(\w* [0,1]\w*) *[CIR]  .*/$1/;
	($field_name, $type, $units) = split / {2,}/, $record;
	$event_file_field_names{$field_name} = $i;
	print STDOUT ("#***debug, event_file_field_names{$field_name}=$i\n")
		if $debug eq 'yes';
}

#Now fill up @record with the rest of the data
@records = <EVENT>;
print STDOUT ("#***debug, reading in records:\n",
	"\trecords[0]=$records[0]\n\trecords[1]=$records[1]\n")
	if $debug eq 'yes';
close EVENT;
return 'okay';

}

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

sub find_key_value_in_records {

# Given the cast value from $_[0] and the field name in
# $_[1], and the records found in @records return the value found 
# with % characters converted to spaces or the value of "nd" if not found.

my ($cast_value, $i, $record, @record, $value, $value_position);

unless (defined $_[0] and defined $_[1]) {return "nd";}

$cast_value = $_[0];
$value_position = $event_file_field_names{$_[1]} -1;

unless (exists $config_param{'ID_cast'} and defined $config_param{'ID_cast'}) {
	&make_log_entry("Cast ID is not defined in configuration file");
	&sendmessage($error, "Cast ID is not defined in configuration file",
		"Cannot continue");
	return "nd";
}
$cast_position = $event_file_field_names{$config_param{'ID_cast'} } - 1;

print STDOUT ("#***debug, cast value=$cast_value, field name=$_[1], ",
	"cast_position=$cast_position, value_position=$value_position\n")
	if $debug eq "yes";
foreach $record (@records) {
	chomp $record;
	print STDOUT ("#***debug, record=$record\n") 
		if $debug eq "yes";
	@record = split / {1,}/, $record;
	print STDOUT ("#***debug, before test: ",
		"record[$cast_position]=$record[$cast_position] ",
		"cast_value=$cast_value\n")
		if $debug eq 'yes';
	if ($record[$cast_position] == $cast_value) {
		$value = $record[$value_position];
		print STDOUT ("#***debug, value=$value\n")
			if $debug eq 'yes';
		return $value;
	}
	else {
		print STDOUT ("#***debug, cast numbers do not match: ",
			"record[cast_position]=$record[$cast_position] ",
			"cast_value=$cast_value\n")
			if $debug eq 'yes';
	}
	
}

return "nd";
}
