#!/opt/perl/bin/perl
use strict;
$ENV{ARCH}='Linux86';
use GPS::DATES;
use GPS::Defaults;
use GOA::StaPos;
use GOA::Util;
use GPS::Coords;
use GOA::StaLoc;
use Cwd;
use Smart::Comments;
use Net::FTP;
use Net::FTP::File;
use File::Basename;
use File::Copy;
use Carp;
my $progname = basename $0;
my $usage = <<EOT;
  $progname date [end_date]
EOT

if ( ! @ARGV ) { print $usage; exit; }

my %par = get_defaults( );

my $sd = shift;
my $ed = $sd;
if ( @ARGV ) {
  $ed = shift;
}

#wait for pbo process to finish

my @ps = grep { ! /$$/ } map { (split($_))[1] } grep { /get_.*rnx_data/ } `ps -cfe`;
print STDERR "ps:|@ps|\n";
while ( @ps ) {
  sleep (6+rand(4));
  #@ps = grep { /get_.*rnx_data/ } `ps -cfe`;
  @ps = grep { ! /$$/ } map { (split($_))[1] } grep { /get_.*rnx_data/ } `ps -cfe`;
  print STDERR "ps:|@ps|\n";
}

my $today = get_date('today','cal,num');
my $jd = get_date( $sd,'jd');
my $ejd = get_date($ed,'jd');
die "bad dates $sd > $ed \n" if $ejd < $jd;
while ( $jd <= $ejd) {
   get_rinex($jd);
   $jd++;
}


sub get_rinex {

   my $date = shift;

   my ($yyyy,$doy) = split(' ',get_date($date,"doy"));
   my $cal = get_date($date,'cal');
   my $gwd = get_date($date,'gwd');

   my $yy = unpack("x2a2",$yyyy);

   my $here = cwd();

   chdir $par{RNX_DIR};

   if ( ! -d $yyyy ) { mkdir $yyyy };

   chdir $yyyy;

   $doy=sprintf("%03d",$doy);

   if ( ! -d $doy ) { mkdir $doy };

   chdir $doy;

   print cwd(),"\n";

  my $sl=GOA::StaLoc->new( file => "$par{STA_INFO_DIR}/sta_loc" );
   
  my @pbo =(); 
  my @Regions = `proj_list -proj pbo-all -nets`;
  chomp @Regions;
  @Regions = map { s/_A//; $_ } grep { /_A$/ } @Regions;
  my %reg = ();
  @reg{@Regions}=@Regions;
  foreach my $s ( keys %{$sl->loc} ) {
       my $h = $sl->loc($s);
       print trim($h->{region}),"\n";
       #next if $h->{region} !~ /(AK|PNW|NCAL|SCAL|RM|RGR|BR|NA|USAB|MX|)/;
       next if ! exists $reg{trim($h->{region})};
       push @pbo,lc $s;
  }
  my @pbo_current=`proj_list -proj pbo-all -sites`; chomp @pbo_current;
  
  #print @pbo;
  #my $coord_file = "$par{GPS_HOME_DIR}/config/pbo/pbo_coords_public.txt";
  #my $coord_file = "$par{STA_INFO_DIR}/sta_loc";
  #my $pbo_coords = GPS::Coords->new( file => $coord_file );
  #my @pbo = map { lc $_ } $pbo_coords->get_col( col => 'name');
  #my $built =  $pbo_coords->select( status => 'Built' );
  #my @pbo_current = map { lc $_ } $pbo_coords->get_col( data => $built , 
  #                                                     col => 'name');       
  
  my %sites=();
  my %current=();
  my %new=();
  @sites{@pbo}=(1)x(@pbo);
  @current{@pbo_current}=(1)x(@pbo_current);

  #print map { "$_ \n" } sort keys %current;
  #print map { "$_ \n" } sort keys %sites;
  #print map {"$_ $current{$_}\n"} qw/p227 p288 p449 p052 p436 p054/;
  #delete @current{qw/p227 p288 p449 p052 p436 p054/};
  #goto LIST;
  my @info =  ( 
       { host => "data-out.unavco.org", 
	     dir  => "/pub/rinex/obs/$yyyy/$doy",
         name  => 'unavco'},
       #{ host => "data-out2.unavco.org", 
	   #  dir  => "/pub/rinex/obs/$yyyy/$doy",
       #  name  => 'unavco-mirror'},
	   { host => "cddis.gsfc.nasa.gov", 
	     dir  => "/pub/gps/data/daily/$yyyy/$doy/${yy}d",
         name  => 'cddis'},
	   { host => "garner.ucsd.edu",
	     dir  => "/pub/rinex/$yyyy/$doy",
             name  => 'sopac'},
	   { host => 'cors.ngs.noaa.gov',
	     dir  => "/cors/rinex/$yyyy/$doy",
             name  => 'cors'},
	 );

#$host = "data-out.unavco.org";
#$dir = "/pub/rinex/obs";
  my (%downloaded,%files,@list,@rnx)=();
  my $password = 'gnet@geology.cwu.edu';
  foreach my $src ( @info ) {	  
    my $host  = $src->{host}; 
    my $dir   = $src->{dir}; 
    my $ag    = uc $src->{name}; 
    print "Connecting to $ag ( $host )";
    my $ftp = Net::FTP->new( "$host",
	          Timeout => 30,
		      Debug => 0,
		      Passive => 1 ) or print ( "Can't connect to host $host: $@\n" );
    if ( ! defined $ftp || ! $ftp ) {
     print " FAILED\n";
     next;
    }
    else {
     print " SUCCESS\n";
    }
    $ftp -> login ( "anonymous", $password ) 
		or print  ( " Couldn't login into $host\n");
    $ftp -> binary () 
	   or print  ( " Couldn't set type to binary in $host\n");
    $ftp -> cwd ( $dir ) 
	   or print  ( " Couldn't change to dir $dir\n");
    
    (@rnx,@list)=(); 
  
    if ( uc($ag) eq 'CORS' ) {
       #@list = $ftp->dir();
       # obtain 4 char. dir. name from list in long directory format
       #@list = grep /^\w{4}$/, map { (split(' ',$_))[7] } @list;
       my $dirinfo_hashref = $ftp->dir_hashref;
       foreach my $remotedir (keys %$dirinfo_hashref) {
           my $remotefile = "$remotedir/$remotedir${doy}0.${yy}d.Z";
           push(@rnx,$remotefile)
       }
       #@rnx = map { "$_/$_${doy}0.${yy}d.Z" } @list;
    }
    elsif ( $ag eq 'PANGA' ) {
  	  @rnx = $ftp->ls("*.*d.bz2");
    }
    else {
  	  @rnx = $ftp->ls("*.*d.Z");
    }
    %files=();
    
    foreach my $r ( @rnx ) {  # Searching $host [===|    ] % done
      my $rnx_site = basename($r);
      my $s =unpack("a4", $rnx_site);
      #if ( exists $sites{$s} ) { 
      if ( exists $sites{$s} && ! -e $rnx_site ) {
        $files{$s} = $r;
      }
    }
    my $nrnx= scalar keys %files;
    my $ok;
   #print (map { "$_\n" } sort values %files);
   foreach my $s ( sort keys %files ) { ### Downloading from $host [===|    ] % done 

     #printf("%03d %4s %s\n",$i++,$s,$files{$s});
     #print "$i $s $files{$s}\n";
     #$i++;
     
     next if -e basename($files{$s});
     $ok=$ftp->get($files{$s});
     #$ok=1 if -e basename($files{$s});
     if ( defined $ok ) {
        $new{$s}=$files{$s} if ! exists $current{$s};
        #print "$i $s $new{$s}\n" if ! exists $current{$s};
        #$i++;
        $downloaded{$s}=$files{$s};
     } else {
        print 'couldn\'t get ', basename($files{$s}),
              'Msg:',$ftp->message; 
     } 
     #last if $i++ > 3; 
   }

   $ftp -> quit() 
        or print  ( " Couldn't quit from $host\n");
  } #end info
 
  #system( "get_brdc",$yyyy,$doy);
  my $i=1;
  print (map { sprintf("%03d %4s %s\n",$i++,$_) } sort keys %new);

  my @n=sort keys %new;

  mk_pos_info( $date, %downloaded );


  my $nc = @n;
  my $nd = scalar keys %downloaded;
  my $summary =<<EOT;
#====================================================================
Summary RINEX Download : $cal ; YYYY,DOY = $yyyy,$doy ; WWWWD = $gwd
Downloaded                    : $nd
---------------------------------------------------------------------
Not in current processing list: $nc
@n
#====================================================================
EOT

 print $summary;

 unlink "$here/getting_unavco_rnx";

}


sub mk_pos_info {
  my $date = shift;
  my %files = @_;
  my $sta_pos = GOA::StaPos->new( file => "$par{STA_INFO_DIR}/sta_pos" );
  #my @sta = $sta_pos->get_col( col => 'sta' , unique => 1);
  my @sta = sort keys %{ $sta_pos->get() };
  my %pos = ();
  @pos{@sta}=();
  #print map { "$_ " } sort keys %pos, "\n";
  my $outdir ="$par{STA_INFO_DIR}/mail_info"; 
  my $site;
  my $opt = "-noid -nosvec -norcvr -nocoords -dir $outdir";
  my @lines;
  foreach my $s ( keys %files ) {
    $site = uc $s;
    #print "checking position for $site ";
    if ( ! exists $pos{$site} ) {
      print "making sta_pos entry $site from $files{$s} ";
      print `rinex2sta_pos -site $s -date $date -hpos -overwrite`; 
      print " done\n";
    }
    unlink glob("$s*.??o");
    unlink glob("$s*.??S");
  }
  #open(my $fh,"|mk_meta $opt") or die "Couldn't open mk_meta $!\n";
  #print $fh @lines;
}
