#!/usr/bin/perl
#
#  zoneWriter 
#
# Program to split zone bulletins into individual reports, then write
# them to a directory structure ~/data/raw/zone/yyyymmdd/stn using the 
# station name as the file name. If the station name is not available then 
# the wmoId number will be used as the station name. The additional reports 
# for the hour are appended to file. 
#
# process command line switches
while ($_ = $ARGV[0], /^-/) {
	 shift;
       last if /^--$/;
	     /^(-v)/ && $verbose++;
}
# process input parameters
if( $#ARGV == 1 ) {
	$datadir = $ARGV[ 0 ] ;
	$yyyymm = $ARGV[ 1 ] ;
	die "yyyymm must be 6 in length: $!\n" if( length( $yyyymm ) != 6 ) ;
	$theyear = substr( $yyyymm, 0, 4 ) ;
	$themonth = substr( $yyyymm, 4 ) ;
} else {
	die "usage: zoneWriter datatdir yyyymm < rawZone $!\n" ;
}

# set interrupt handler
$SIG{ 'INT' }  = 'atexit' ;
$SIG{ 'KILL' }  = 'atexit' ;
$SIG{ 'TERM' }  = 'atexit' ;
$SIG{ 'QUIT' }  = 'atexit' ;


chdir( "$datadir" ) ;

# Now begin parsing file and decoding observations breaking on cntrl C
$/ = "\cC" ;

# set select processing here from STDIN
START:
while( 1 ) {
	open( STDIN, '-' ) ;
	vec($rin,fileno(STDIN),1) = 1;
	$timeout = 1200 ; # 20 minutes
	$nfound = select( $rout = $rin, undef, undef, $timeout );
	# timed out
	if( ! $nfound ) {
		print "Shut down, time out 20 minutes\n" ;
		atexit() ;
	}
	atexit( "eof" ) if( eof( STDIN ) ) ;

	# Process each line of zone bulletins, header first
	$_ = <STDIN> ;
	s#\cC## ;
	s#\cM##g ;
	s#\cA\n## ;
	s#\c^##g ;
 
	s#\d\d\d \n## ;
	s#\w{4}\d{1,2} \w{4} (\d{2})(\d{2})(\d{2}).*\n## ;
	$bday = $1 ;
	$bhour = $2 ;
	$bhour = "23" if( $bhour eq "24" ) ;
	$bmin = $3 ;
	next unless ( $bday && defined( $bhour ) && defined( $bmin ) ) ;
	next if( $bmin > 59 || $bhour > 23 || $bday > 31 ) ;
	next unless( s#^(RDF|PFM).*\n## ) ;
	# check for valid bulletin times against current time
	$cday = (gmtime())[ 3 ] ;
	$chour = (gmtime())[ 2 ] ;
	# skip bulletins over 24 hours old or in the future
	if( $bday == $cday ) {
		next if( $bhour > $chour ) ;
	} else { #  $bday != $cday, skip over day old reports
 		next if( $bday < $cday -1 ) ;
 		if( $bday > $cday ) {
			next if( $cday != 1 || $bday < 28) ;
		}
 		next if( $bhour < $chour ) ;
	}
	# Separate bulletins into reports 
	if( /=\n/ ) {
		s#=\s+\n#=\n#g ;
		@LINE = split( /=\n/ ) ;
	} else {
		@LINE = split ( /\n/ ) ;
	}
	$rptName = "" ;
	$rptTime = "" ;
	$insideRpt = 0 ;
	$report = "" ;
	$i = -1 ;
	while( $i <= $#LINE ) { # Process each bulletin by line 
		$_ = $LINE[ ++$i ] ;
		if( s#^(\w{2})(Z|C)(\d{3})## ) { # create zone names
			$rptName = "$1$2" ;
			$lastNum = $3 ;
			undef( @RPTS ) ;
			push( @RPTS, "$rptName$lastNum" ) ;
			s#\s*##g ; # some zones pad with spaces
			if( ! /-\d{6}-$/ ) { # check if valid zone line
				$_ .= $LINE[ ++$i ] ;
				s#\s*##g ; # some zones pad with spaces
				next unless(/-\d{6}-$/ ) ;
			}
			while( length() > 6 ) { # stop on date
				if( /^-/ ) {
					if( s#^-(\d{6})## ) {
						$rptTime = "-$1-" ;
						last ;
					} elsif( s#^-(\w{3})(\d{3})## ) {
						$rptName = "$1" ;
						$lastNum = $2 ;
					} elsif( s#^-(\d{3})## ) {
						$lastNum = $1 ;
					} else {
						print "zoneWrite: ",
						"Bad: $rptName$lastNum:$_\n" ;
						$rptTime = "" ;
						last ;
					}
					push( @RPTS, "$rptName$lastNum" ) ;
				} elsif( /^\>/ ) { # expand zones
					s#^\>(\d{3})## ;
					$endNum = $1 ;
					for( $lastNum++ ; $lastNum <= $endNum; 
						$lastNum++){	
						push( @RPTS, $rptName . 
							sprintf( "%03d",
							$lastNum )) ;
					}
				} else {
					print "zoneWriter: ",
						"Bad: $rptName$lastNum:$_\n" ;
					$rptTime = "" ;
					last ;
				}
				#print "$_\n" ;
			} # end while
			$insideRpt = 1 if( $rptTime ) ;
			#$rptTime = $_ ;
			next ;
		}
		next unless( $insideRpt ) ;
		$report .=  "$_\n"  ;
		if( /^\$\$/ ) { # done with this report
			$yyyymmdd = $yyyymm . $bday ;
			mkdir( "$yyyymmdd", 0775 ) if( ! -e "$yyyymmdd" ) ;
			chdir( "$yyyymmdd" ) ;
			for( $j = 0; $j <= $#RPTS; $j++ ) {
				open( ZONE, ">>$RPTS[ $j ]" ) ;
				print ZONE "$RPTS[ $j ]$rptTime\n" ;
				print ZONE "$report\n" ;
				close ZONE ;
				#print "$RPTS[ $j ]", "\n" ;
			}
			chdir( ".." ) ;
			$rptName = "" ;
			$rptTime = "" ;
			$insideRpt = 0 ;
			$report = "" ;
		}
	} # end foreach line
} # end while( 1 )
atexit( "eof" );
exit( 0 ) ; #should never get here

# execute at exit
sub atexit
{
local( $sig ) = @_ ;

if( $sig eq "eof" ) {
	print "eof on STDIN --shutting down\n" ;
} elsif( defined( $sig )) {
	print "Caught SIG$sig --shutting down\n" ;
}
exit( 0 ) ;

} #end atexit

