#!/usr/bin/tclsh8.5
#
# $Id: ea3f9377f8127e8e410d20c05b49e1b2d53e7a2d $
#
package require fileutil;

## The common defaults
set filters_init_file "/usr/local/libexec/nbsp/filters.init";
if {[file exists $filters_init_file] == 0} {
    puts "uafilter disabled: $filters_init_file not found.";
    return 1;
}
source $filters_init_file;
unset filters_init_file;

if {$filters_init_status == 1} {
    return 1;
}
unset filters_init_status;

# packages
package require nbsp::util;
package require nbsp::periodic;

# Load the functions library before gisfilter.init since gisfilter.init
# uses some of them.
#
# $Id: 19eccca8b7a87d67625a294133294e4b3597fe77 $
#
proc filter_sat {rc_varname} {

    global gisfilter;
    upvar $rc_varname rc;

    filter_sat_create_gini rc;

    foreach bundle $gisfilter(sat_bundlelist) {
	set regex $gisfilter(sat_bundle,$bundle,regex);
	if {[filterlib_uwildmat $regex $rc(wmoid)] == 0} {
	    continue;
	}
	filter_sat_convert_gini rc $bundle;
    }
}

proc filter_sat_create_gini {rc_varname} {
    #
    # Write the gini file
    #
    global gisfilter;
    upvar $rc_varname rc;

    set data_savedir [subst $gisfilter(sat_outputfile_dirfmt,gini)];
    set data_savename [subst $gisfilter(sat_outputfile_namefmt,gini)];

    file mkdir $data_savedir;
    set data_path [file join $data_savedir $data_savename];
    set datafpath [file join $gisfilter(datadir) $data_path];

    set status [catch {
        # Sat files do not have a ccb
	file copy -force $rc(fpath) $data_path;
    } errmsg];

    if {$status != 0} {
        file delete $data_path;
        log_msg $errmsg;
        return -code error $errmsg;
    }

    filter_sat_insert_inventory $data_savedir $datafpath;
    make_sat_latest $data_savedir $data_savename;

    # Reuse the rc(fpath) variable to point to the newly created gini file.
    set rc(fpath) $datafpath;
}

proc filter_sat_convert_gini {rc_varname bundle} {

    global gisfilter;
    upvar $rc_varname rc;

    set fmtlist $gisfilter(sat_bundle,$bundle,fmt);
    set ginifpath $rc(fpath);

    # nbspsatgis command line options
    set option(asc) "-a";
    set option(dbf) "-f";
    set option(info) "-o";
    set option(shp) "-p";
    set option(shx) "-x";
    set option(csv) "-v";
    set cmd_options [list];

    foreach fmt $fmtlist {
	set data_savedir($fmt) [subst $gisfilter(sat_outputfile_dirfmt,$fmt)];
	set data_savename($fmt) \
	    [subst $gisfilter(sat_outputfile_namefmt,$fmt)];
	file mkdir $data_savedir($fmt);
	set data_path($fmt) \
	    [file join $data_savedir($fmt) $data_savename($fmt)];
	set datafpath($fmt) [file join $gisfilter(datadir) $data_path($fmt)];

	if {[info exists option($fmt)]} {
	    lappend cmd_options $option($fmt) $datafpath($fmt);
	}
    }

    set cmd [concat [list nbspunz $ginifpath | nbspsatgis -b] $cmd_options];

    set status [catch {
	eval exec $cmd;
    } errmsg];

    # Append the wmo header data to the info file (if "info" is in fmtlist)
    if {([lsearch $fmtlist info] != -1) && ($status == 0)} {
	set infodata "rootname: [file rootname $data_savename(info)]\n";
	foreach k [list wmoid] {
	    append infodata "$k: $rc($k)\n";
	}

	set status [catch {
	    ::fileutil::appendToFile $datafpath(info) $infodata;
	} errmsg];
    }

    if {$status != 0} {
	foreach fmt $fmtlist {
	    file delete $datafpath($fmt);
	}
	log_msg $errmsg;
	return;
    }

    # Insert each one in the cleanup inventory and create the latest link
    foreach fmt $fmtlist {
	filter_sat_insert_inventory $data_savedir($fmt) $datafpath($fmt);
	if {$gisfilter(sat_latest_enable) != 0} {
	    make_sat_latest $data_savedir($fmt) $data_savename($fmt);
	}
    }
}
#
# $Id: 00306adab489bb0cd1fedafc307f16015d33c6d6 $
#
proc filter_rad {rc_varname} {

    global gisfilter;
    upvar $rc_varname rc;

    filter_rad_create_nids rc;

    foreach bundle $gisfilter(rad_bundlelist) {
	set regex $gisfilter(rad_bundle,$bundle,regex);
	if {[filterlib_uwildmat $regex $rc(awips)] == 0} {
	    continue;
	}
	filter_rad_convert_nids_shp rc $bundle;
    }
}

proc filter_rad_create_nids {rc_varname} {
    #
    # Write the nids file
    #
    global gisfilter;
    upvar $rc_varname rc;

    set seq $rc(seq);
    set fpath $rc(fpath);

    set data_savedir [subst $gisfilter(rad_outputfile_dirfmt,nids)];
    set data_savename [subst $gisfilter(rad_outputfile_namefmt,nids)];

    file mkdir $data_savedir;
    set data_path [file join $data_savedir $data_savename];
    set datafpath [file join $gisfilter(datadir) $data_path];

    set status [catch {
	#
	# The files are saved without the gempak header/footer (-t) and
	# the -w flag is passed to wait for the nids file to be created
	# before continuing to create the gis files.
	#
	filterlib_cspool_nbspfile \
	    $seq $fpath $data_savedir $data_savename -t -w;

	## filterlib_nbspfile $seq $fpath $data_savedir $data_savename -t;
    } errmsg];

    if {$status != 0} {
        file delete $data_path;
        log_msg $errmsg;
        return -code error $errmsg;
    }

    filter_rad_insert_inventory $data_savedir $datafpath;
    make_rad_latest $data_savedir $data_savename;

    # Reuse the rc(fpath) variable to point to the newly created nids file.
    set rc(fpath) $datafpath;
}

proc filter_rad_convert_nids_shp {rc_varname bundle} {

    global gisfilter;
    upvar $rc_varname rc;

    set fmtlist $gisfilter(rad_bundle,$bundle,fmt);
    set nidsfpath $rc(fpath);

    # nbspradgis command line options
    set option(dbf) "-f";
    set option(info) "-o";
    set option(shp) "-p";
    set option(shx) "-x";
    set option(csv) "-v";
    set cmd_options [list];
 
   foreach fmt $fmtlist {
	set data_savedir($fmt) [subst $gisfilter(rad_outputfile_dirfmt,$fmt)];
	set data_savename($fmt) \
	    [subst $gisfilter(rad_outputfile_namefmt,$fmt)];
	file mkdir $data_savedir($fmt);
	set data_path($fmt) \
	    [file join $data_savedir($fmt) $data_savename($fmt)];
	set datafpath($fmt) [file join $gisfilter(datadir) $data_path($fmt)];

	if {[info exists option($fmt)]} {
	    lappend cmd_options $option($fmt) $datafpath($fmt);
	}
    }

    #
    # The ccb header must be removed for nbsnidsshp (use -C).
    # The -F option instructs nbspradgis to apply the built-in filtering
    # options of the data (e.g., ignoring polygons with level values
    # less than 1.
    #
    if {[regexp $gisfilter(rad_unz) $rc(awips1)]} {
	set cmd [concat [list nbspunz -C $nidsfpath | nbspradgis -b -D] \
		     $cmd_options];
    } else {
	#
	# If the nids are saved with the gempak header then we have to use
	# -c $filterslib(gmpk_header_size)
	#
	set cmd [concat [list nbspradgis -b -D] $cmd_options $nidsfpath];
    }

    set status [catch {
	eval exec $cmd;
    } errmsg];

    # Append the wmo header data to the info file (if "info" is in fmtlist)
    if {([lsearch $fmtlist info] != -1) && ($status == 0)} {
	set infodata "rootname: [file rootname $data_savename(info)]\n";
	foreach k [list awips] {
	    append infodata "$k: $rc($k)\n";
	}

	set status [catch {
	    ::fileutil::appendToFile $datafpath(info) $infodata;
	} errmsg];
    }

    if {$status != 0} {
	foreach fmt $fmtlist {
	    file delete $datafpath($fmt);
	}
	log_msg $errmsg;
	return;
    }

    # Insert each one in the cleanup inventory and create the latest link
    foreach fmt $fmtlist {
	filter_rad_insert_inventory $data_savedir($fmt) $datafpath($fmt);
	if {$gisfilter(rad_latest_enable) != 0} {
	    make_rad_latest $data_savedir($fmt) $data_savename($fmt);
	}
    }
}
#
# $Id: 843f187bb8b13257b4666cf21fbd8c54ac6c8a8f $
#
proc filter_rad2 {rc_varname} {

    global gisfilter;
    upvar $rc_varname rc;

}
#
# $Id: 97c91961028c610850abe74bf3b56bcfd25921fe $
#

# These functions are need in the filter in order to create the latest
# file for the data (gini) file. The nbspwct program has its own copy
# of the function in order to create the link for the data files produced
# by WCT.

proc make_rad_latest {savedir savename {level2flag 0}} {

    global gisfilter;

    set rad_latestname "";

    if {$level2flag == 0} {
	if {$gisfilter(rad_latest_enable) != 0} {
	    set rad_latestname $gisfilter(rad_latestname);
	}
    } elseif {$gisfilter(rad2_latest_enable) != 0} {
	set rad_latestname $gisfilter(rad2_latestname);
    }

    if {$rad_latestname eq ""} {
	return;
    }
    
    make_latest $savedir $savename $rad_latestname;
}

proc make_sat_latest {savedir savename} {

    global gisfilter;

    if {($gisfilter(sat_latest_enable) == 0) || \
	($gisfilter(sat_latestname) eq "")} {

	return;
    }

    make_latest $savedir $savename $gisfilter(sat_latestname);
}

proc make_latest {savedir savename latestname} {
#
# Create a link to the newest file.
#
    append linkpath $latestname [file extension $savename];
    set latest $savename;

    set currentdir [pwd];
    cd $savedir;

    if {[file exists $latest] == 0} {
	cd $currentdir;
	return;
    }

    set status [catch {
        file delete $linkpath;
        # file link -symbolic $linkpath $latest;
	exec ln -s $latest $linkpath;
    } errmsg];

    cd $currentdir;
}
#
# Functions to support the inventory
#

proc filter_insert_inventory {invsubdir savedir fpathout} {
# 
# See the function with this same name in the rstfilter.lib for the meaning
# of the "savedir" argument.
#
    global gisfilter;

    # The gis invdir must exist
    if {[file isdirectory $gisfilter(invdir)] == 0} {
	log_msg "No $gisfilter(invdir)";
	return;
    }

    # The inventory files are saved in hourly subdirs within
    # gis/<invsubdir>. E.g.,
    # gis/nexrad/nids/<yyyymmddhh>/nexrad.nids.mhx.ncr
    #
    set parentdir [file join $gisfilter(invdir) $invsubdir \
       [clock format [clock seconds] -format $gisfilter(invformat) -gmt true]];
    file mkdir $parentdir;

    set invfile_name [join [file split $savedir] "."]
    set invfile [file join $parentdir $invfile_name];

    filterlib_file_append $invfile $fpathout;
}

proc filter_rad_insert_inventory {savedir fpathout} {

    global gisfilter;

    if {$gisfilter(rad_inv_enable) == 0} {
	return;
    }

    filter_insert_inventory $gisfilter(radinvsubdir) $savedir $fpathout;
}

proc filter_sat_insert_inventory {savedir fpathout} {

    global gisfilter;

    if {$gisfilter(sat_inv_enable) == 0} {
	return;
    }

    filter_insert_inventory $gisfilter(satinvsubdir) $savedir $fpathout;
}

foreach _init_name [list "gisfilter.init1" "gisfilter.init2"] {
    set _init_file [file join $common(libdir) $_init_name];
    if {[file exists $_init_file] == 0} {
        log_msg "gisfilter disabled: $_init_file not found.";
        return 1;
    }
    source $_init_file;
}
unset _init_file;
unset _init_name;

proc main {argc argv} {

    global gisfilter;
    global errorInfo;

    # The gisfilter data directory must exist
    if {[file isdirectory $gisfilter(datadir)] == 0} {
	log_msg "$gisfilter(datadir) does not exist.";
	return 1;
    }

    cd $gisfilter(datadir);
	
    # gets returns -1 on eof. In addition the server explicitly
    # signals the filters to quit by sending a blankline
    # (gets returns 0 in this case, and finfo is "").

    while {[gets stdin finfo] >= 0} {
	if {$finfo == ""} {
	    log_msg "Received request to quit.";
	    break;
	}

	set status [catch {process $finfo} errmsg];
	if {$status == 1} {
	    log_msg "Error processing $finfo";
	    log_msg $errmsg;
	    log_msg $errorInfo;
	}
    }
}

proc process {finfo} {

    global gisfilter;

    set _cmd [list filterlib_get_rcvars rc $finfo];

    # If rad is enable, extract the rc(radxxx) parameters
    if {$gisfilter(rad_enable) != 0} {
        lappend _cmd "-dorad";
    }

    # If sat is enable, extract the rc(satxxx) parameters
    if {$gisfilter(sat_enable) != 0} {
        lappend _cmd "-dosat";
    }

    eval ${_cmd};

    if {($gisfilter(sat_enable) != 0) && \
	([filterlib_uwildmat $gisfilter(sat_regex) $rc(wmoid)] == 1)} {
	filter_sat rc;
    } elseif {($gisfilter(rad_enable) != 0) && \
	([filterlib_uwildmat $gisfilter(rad_regex) $rc(wmoid)] == 1)} {
	filter_rad rc;
    } elseif {($gisfilter(rad2_enable) != 0) && \
	([filterlib_uwildmat $gisfilter(rad2_regex) $rc(wmoid)] == 1)} {
	filter_rad2 rc;
    }

    set status [catch {
        ::nbsp::periodic::run;	# Run the registered periodic functions
    } errmsg];
    
    if {$status != 0} {
    	log_msg $errmsg;
    }
}

proc gisfilter_run_schedule {} {
#
# This is the function that is registered with the periodic library.
#
    global gisfilter;

    if {$gisfilter(scheduler_enable) == 0} {
        return;
    }

    ::nbsp::periodic::scheduler $gisfilter(schedule);
}

#
# Dynamic initialization
#

# Register the scheduler to run every minute
::nbsp::periodic::register gisfilter_run_schedule \
	$gisfilter(schedule_run_period);

#
# main
#
filterlib_init;		# open the cpool if enabled
main $argc $argv;
filterlib_end;		# close the cpool if enabled
