#!/opt/perl/bin/perl
use strict;
#use lib "$ENV{GPS_HOME_DIR}/bin/pm";
use GPS::DATES qw( get_date jd2cal );
use GPS::Defaults;
use Net::FTP;
use Net::Netrc;
use File::Basename;
use File::Copy;
use Getopt::Long;
use Carp;
use Cwd;

my $progname = basename $0;
my $MIN_NUM_SITES = 950;
#my $MIN_NUM_SITES = 680;
my %par =  get_defaults();
my $proj = '';
my $ac =  'igs';
my $help = '';
my $force = 0;
my $args = @ARGV;
my ($date,$sdate,$edate,$gpsw)=('')x4;
#products
my  %product  = (  'pbo-rapid'        =>  'a' ,
                   'pbo-week'         =>  'b' ,
                   'pbo-amb-redo'     =>  'b' ,
                   'pbo-supplemental' =>  'c' ,
                   'pbo-rerun'        =>  'c' ,
                   'pbo-camp-d'       =>  'd' ,
                   'pbo-final'        =>  'e' ,
		   'pbo-reanalysis'   =>  'e' ,
                   'pbo-supplemental6' =>  'f' ,
                 );

my $update = '';
my $met=0;
GetOptions( 'proj=s'   => \$proj,
            'update' => \$update,
            'date:s'   => \$date,
            'sdate:s'  => \$sdate,
            'ac:s'     => \$ac,
            'gpsw:s'   => \$gpsw,
            'edate:s'  => \$edate,
            'met'      => \$met,
            'help'     => \$help,
            'force'    => \$force,
) or die "Error in options\n";

if ( ! $args || $help ) { usage(); exit; }

if ( ! exists $product{$proj} ) {
  croak "Unknown PBO project $proj\n";
}


if ( ! ( $date || $sdate || $gpsw ) ) {
  croak "You must provide -date/-sdate/-gpsw \n";
}

#die "Temporarily disabled\n";

if ( $gpsw ) {
   $sdate = $gpsw.'0';
   $edate = $gpsw.'6';
}
elsif ( $date || $sdate ) {
 $sdate = $date  if ! $sdate;
 $edate = $sdate if ! $edate;
}

my $cal = get_date($sdate,'cal');
my($yyyy) = split /-/,$cal;
my $pd  = "$par{RAW_COMB_DIR_ARCHIVE}/$ac/$proj/$yyyy";

if ( ! -e $pd) {
  carp "Dir $pd doesn't exists $!\n";
}

chdir $pd or croak "couldn't change to $pd $!\n";

my $sjd = get_date($sdate,'jd');
my $ejd = get_date($edate,'jd');

my $min_par = 3*$MIN_NUM_SITES;
$min_par = 3*3 if $proj =~ 'pbo-supplemental' || $proj =~ /^pbo-camp/ || $proj =~ /pbo-final/ || $proj =~ /pbo-reanalysis/;
my @upload_list=();
my $files;
while ( $sjd <= $ejd ) {
  my $cal = jd2cal($sjd);
  $files = get_files( proj => $proj,
                      date => $cal,
                    );
  if ( check_files( files => $files, 
                    force => $force, 
                    min_par => $min_par ) ) {
     foreach my $k ( keys %$files ) {
        push @upload_list, $files->{$k};
     }
  } 
  else {
    print "failed checking $cal\n"; 
  }

  $sjd++
} 
if ( ! @upload_list ) { 
  croak "No upload list\n"; 
}
#print map { "uploading $_\n" } @upload_list;
my $host= 'chandler.mit.edu';
my $acc = Net::Netrc->lookup($host) 
             or croak "Couldn't find $host in .netrc\n" ;

my ($l,$p,undef) = $acc->lpa;

my $ftp = Net::FTP->new(  $host ,
                         Timeout => 60,
                         Debug   => 0,
                         Passive => 1
                      ) or croak "Can't connect to $host : $@\n";
my $acdir = 'incoming/ACC_PBO/CWU';
my $ok = '';
if ( $ftp ) {
    $ftp->login($l,$p) or croak "Couldn't login into $host : $@\n";
    $ftp->binary();
    $ftp->cwd($acdir);
    foreach my $f ( @upload_list ) {
        my $remote_file = $f;
        $remote_file .= '.update' if $update;
        $ok='';
        $ftp->put($f,$remote_file) 
              or carp "Couldn't upload file $f into $host: $@\n";
        ($ok) = $ftp->ls($remote_file);
         print ( $ok eq $remote_file ? "$f UPLOADED\n": "$f NOT UPLOADED\n");
    }
    $ftp->quit() or croak "Couldn't quit from $host $@\n";
}

sub usage {

my $u =<<EOT;

$progname uploads SINEX files to PBO_ACC

Usage:	
   $progname -proj proj_name [-date date_str] 
              [-sdate start_date_str] [-edate end_date_str]
              [-gpsw gps_week] 
  
date_str: 2005,123    year,doy
          2005-05-01  calendar
          05MAY01     calendar2 
          20050501    num calendar
          13340       GPS Week+day of week  	



see gpsdate for date formats.

Examples:

  upload 1 day
  $progname -proj pbo-rapid -date 2005,123 

  several days
  $progname -proj pbo-rapid -date 2005,123 -edate 2005,130 
  $progname -proj pbo-rapid -sdate 2005,123 -edate 2005,130 

  a whole GPS week, DO NOT include the day of the week.
  You can upload one or several days using the -date/-edate flags
  and passing the GPS week + day in GPS week as a date.
  
  $progname -proj pbo-rapid -gpsw 1364 
  
  
Marcelo Santillan
Geodesy Lab & PANGA facility
Central Washington University

July 2005
updated 20060608

EOT

print $u;

}

sub get_files {
   my %opt = (
     proj => '',
     date => '',
     @_,
   );
   my $cal  = get_date($opt{date},'cal,num');
   my $gwd  = sprintf("%05d",get_date($cal,'gwd'));
   #my $gpsw = $gwd; $gpsw =~ s/.$//;
   my $p = $product{$proj};
   my $files={};
   
   if ( $met ) {
     $files->{met} = "CWU$gwd.$cal.$p.met.gz";
   }
   else {
     $files = { snx => "CWU$gwd.$cal.$p.snx",
                 rms => "cwu$gwd.$cal.$p.rms",
                 met => "CWU$gwd.$cal.$p.met.gz",
               };
   }
   return $files 
}

sub check_files {
   my %opt = (
     files   => '',
     force   => 0,
     min_par => 3*$MIN_NUM_SITES,
     @_,   
   );
  croak "No files to check ! \n" if ! $opt{files};
  print "Current directory ",getcwd,"\n";
  my $snx = $opt{files}{snx};
  my $rms = $opt{files}{rms};
  my $met = $opt{files}{met};
  my ($ok,$okrms,$oksnx,$okmet) = (0)x3;
  if ( -e $met ) { $okmet=1; }
  else { print "No Met file\n"; }
  if ( -e $rms ) { $okrms=1; }
  else { print "No RMS file\n"; }
  if ( -e $snx ) {
     open (my $fh,"< $snx" ) or croak "couldn't open $snx $!\n";
     my @f = split ' ', <$fh>; 
     close ($fh);
     my $npar   = $f[8] =~ /^\d+$/ ? $f[8] : 0;
     my $nsites = $npar/3;
     my $date = get_date( (split /\./,$snx)[1],'cal') ;
     print "$snx : $npar PARAMETERS ON $date == $nsites SITES\n"; 
     $oksnx= $opt{force}             ?   1:
             $npar >=  $opt{min_par} ?   1:
                                         0;
     if ( $npar < $opt{min_par} ) {
       my $msg = <<EOM;
Warning: $snx npar=$f[8] $npar < $opt{min_par}
nsites : $nsites
MIN_NUM_SITES : $MIN_NUM_SITES
$snx NOT UPLOADED
EOM
       mail_this( message => $msg,
                  to      => "$par{GPS_USER}\@geology.cwu.edu",
                  subject => "[Processing]: $snx npar=$npar",
                );
       #$oksnx = 0 if ! $opt{force};
     }
  } else {
	  print "Couldn't find $snx\n";
  }
  $ok = $oksnx && $okrms && $okmet ? 1 : 0;  
  #print "ok $opt{force} $oksnx $okrms $ok\n";
  return $ok
}

sub mail_this {
   my %opt = (
      message => '',
      subject => '',
      to      => "$par{GPS_USER}\@geology.cwu.edu",
      @_,
   );
  open ( my $mh ,"| mail -s '$opt{subject}' $opt{to}" ) 
    or croak "Couldn't open mail $!\n";
  print $mh "$opt{message}\n.\n";
}
