#!/opt/perl/bin/perl
use strict;
use GPS::DATES;
use GPS::Defaults;
use GPS::NetSites;
use GOA::Util;
use GOA::StaPos;
use GOA::StaSvec;
use GOA::StaId;
use GOA::StaRcvr;
use GOA::StaLoc;
use File::Basename;
use Pod::Text::Termcap;
use Getopt::Long;
use Carp::Always;
my $progname = basename $0;
my ($proj,$ac,$date,$amb,$ppp,$help,$archive);
my ($cal,$yyyy,$yy,$doy,$gwd,%ns);
my $types='';
my $rtypes='';
my $nmax=0;
$ac='igs';
my $orb='---';
my $args = @ARGV;
GetOptions( 'proj:s' => \$proj,
            'date:s' => \$date,
            'ac:s'   => \$ac,
            'orb:s'  => \$orb,
            'amb'    => \$amb,
            'ppp'    => \$ppp,
            'fields:s' => \$types,
            'rfields:s' => \$rtypes,
            'nmax:i' => \$nmax,
            'archive' => \$archive,
            'help' => \$help,
          ) or die "Error in options\n";

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

if ( $date ) {
   $cal=get_date($date,'cal');
   ($yyyy,$doy)=split ' ', get_date($cal,'doy');
   $yy=unpack 'x2a2',$yyyy;
   $gwd=get_date($cal,'gwd');
}
else {
   warn "\nNo date supplied\n\n";
   usage();
   exit 1;
}

die "No project name\n" if ! $proj;

#if ( $proj eq 'pbo-rapid' ) {
#  $ac = 'igs';
#  $orb='rapid';
#  $ppp=1; $amb=0;
#}
#elsif ( $proj =~ /^pbo-week/ ) {
#  $ac = 'igs';
#  $orb='final';
#  $ppp=0; $amb=1;
#}
#$ac = 'ig1' if $proj eq 'pbo-final';

my $pns=GPS::NetSites->new( proj => $proj );
my @psites=$pns->sites;
my %sn=$pns->site_net;


my %par=get_defaults( );
my $pos=GOA::StaPos->new( file => "$par{STA_INFO_DIR}/sta_pos" );
my $id=GOA::StaId->new( file => "$par{STA_INFO_DIR}/sta_id" );
my $svec=GOA::StaSvec->new( file => "$par{STA_INFO_DIR}/sta_svec" );
my $rcvr=GOA::StaRcvr->new( file => "$par{STA_INFO_DIR}/sta_rcvr" );
my $loc=GOA::StaLoc->new( file => "$par{STA_INFO_DIR}/sta_loc" );

my %stats=();

my ($k,$rev,$slips,$site,$ps,$ii,$sv,$rc,$lc,$size,$net,$pchi,$achi,$prms,$rrms,$qm_ep,$adpos,$pdpos,$legend);

downloaded_rnx_stats( $proj,$yyyy,$doy );

ppp_stats($ac,$yyyy,$cal);

if ( $amb ) {
  net_stats($proj,$ac,$yyyy,$cal);
}


format STATS_HEADER =
 +-------------------------------------------------------------------------------------------------------------------------------------------+  
 |                         RANGE     PHASE     PPP        AMB        PPP       AMB        Cycle  QM Epochs  RNX                              |
 | nth    Site   Net       RMS(mm)   RMS(mm)   Chi**2     Chi**2     DPOS(m)   DPOS(m)    Slips  (percent)  Size(Kb)   Pos Svec Id  Loc Rcvr |
 +-------------------------------------------------------------------------------------------------------------------------------------------+
.

format STATS =
   @<<<<< @<<<<  @<<<<<<<  @<<<<<<<  @<<<<<<<  @<<<<<<<<  @<<<<<<<<  @<<<<<<<< @<<<<<<<<  @<<<<  @<<<<<<<   @<<<<<<<<  @<< @<<  @<< @<< @<<   
   $k,    $site, $net,     $rrms,    $prms,    $pchi,     $achi,     $pdpos,   $adpos,    $slips,$qm_ep,    $size,     $ps,$sv, $ii,$lc,$rc
.

my @stat_sites;
my @statypes=map { uc $_ } split(',',$types);
my %RT=();
my @rt= map { uc $_ } split(',',$rtypes);
   @RT{@rt}=@rt;
   push @statypes,@rt;
my $pa= $amb ? 'amb' : 'ppp';
my %ST=( RANGE_RMS => 'range_rms',
         PHASE_RMS => 'phase_rms',
         PPP_CHI   => 'ppp_chi',
         AMB_CHI   => 'amb_chi',
         RMS => 'phase_rms', 
         CHI => "${pa}_chi",
         SLIPS => 'cycle_slips',
         QM_EPOCHS => 'percent_daily_qm_epochs',
         RNX_SIZE => 'rnx_size',
         DPOS    => "dpos_$pa",
         PPP_DPOS => 'dpos_ppp',
         AMB_DPOS => 'dpos_amb',
         CYCLE_SLIPS => 'cycle_slips',
         ALL     => 'ALL',
         POS     => 'pos',
         ID      => 'id',
         SVEC    => 'svec',
         LOC     => 'loc',
         RCVR    => 'rcvr',
       );

my @all_sites = grep { /[a-z0-9_]{4}/ } keys %stats;
       
$nmax= scalar keys %stats if ! $nmax;
my @rnx_sites= grep { defined $stats{$_}{rnx_size} } @all_sites;
my $downloaded_sites=@rnx_sites;
my @proc_sites= grep { defined $stats{$_}{"dpos_$pa"} } @all_sites;
my $processed_sites=@proc_sites;
my @not_proc_sites = grep { not defined $stats{$_}{"dpos_$pa"} } @all_sites;
#my $snp = @rnx_sites - @proc_sites;
my $snp = @not_proc_sites;
my $proj_sites = scalar @psites;
my $nnets = scalar @{$pns->nets};

format HEADER =
 +-------------------------------------------------------------------------------------------------------------------------------------------+
 | Summary for project : @<<<<<<<<<<<<<<<<<<<                                                                                                |
                         $proj 
 | Date                : @<<<<<<<<<< ; DOY: @<<<  ; WWWWD: @<<<<<<                                                                           |             
                         $cal,              $doy,          $gwd, 
 | Processing type     : @<<<<<                                                                                                              |
                         $pa
 | AC                  : @<<<<<<<<<                                                                                                          |
                         $ac
 | Orbit Type          : @<<<<<<<<<                                                                                                          |
                         $orb
 | Downloaded sites    : @<<<<<<<<                                                                                                           |
                         $downloaded_sites
 | Processed  sites    : @<<<<<<<<                                                                                                           |
                         $processed_sites
 | Sites in List       : @<<<<<<<<                                                                                                           |
                         $proj_sites
 | Number of Networks  : @<<<<                                                                                                               |
                         $nnets
 | SITES NOT PROCESSED : @<<<<<<                                                                                                             |
                         $snp
.

format LEGEND =
 +-------------------------------------------------------------------------------------------------------------------------------------------+
 | @|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |
   $legend
.

$~='HEADER';
write;
foreach my $st ( 'NOT_PROCESSED', sort @statypes ) {
  my $n=sprintf("% 4d",$nmax);
     $snp=sprintf("% 4d",$snp);

  
  if ( $st eq 'ALL' ) {
     $legend = "ALL $n sites";
     if ( $amb ) {
        @stat_sites = sort { $stats{$a}{net} cmp $stats{$b}{net} } @all_sites;
     }
     else {
        @stat_sites = sort @all_sites; 
     }
  }
  elsif ( exists $ST{$st} ) {
    $rev = exists $RT{$st} ? 1 : 0;
    delete $RT{$st} if exists $RT{$st};
    my $sl= ! $rev ? 'smallest' : ' largest ';
    $legend = "$n sites $sl $st";
    @stat_sites = get_sites($ST{$st},$nmax,$rev);
  }
  elsif ( $st eq 'NOT_PROCESSED') {
    @stat_sites= sort { $stats{$a}{net} cmp $stats{$b}{net}  } @not_proc_sites;
    $legend = "$snp SITES(s) NOT PROCESSED";
   #@stat_sites= sort grep { ! defined $stats{$_}{"dpos_$pa"} } 
  }
 
  $~ = 'LEGEND';
  write;
 
  if ( @stat_sites ) {
    $~= 'STATS_HEADER';
    write;
    $~= 'STATS';
  }
  else {
    next;
  }
  $k=1;
  foreach my $s ( @stat_sites ) {
     next if ! trim($s);
     $site = uc $s;
     $size= sprintf("%-d",$stats{$s}{rnx_size}/1024) || '---';
     $ps= $stats{$s}{'pos'};
     $ii= $stats{$s}{id}; 
     $sv= $stats{$s}{svec}; 
     $rc= $stats{$s}{rcvr};
     $lc= $stats{$s}{loc};
     $net=$stats{$s}{net} || '---';
     $slips=$stats{$s}{cycle_slips} || '---';
     $pdpos=$stats{$s}{dpos_ppp} || '---';
     $adpos=$stats{$s}{dpos_amb} || '---';
     $pchi= $stats{$s}{ppp_chi}; 
     $achi= $stats{$s}{amb_chi}; 
     $achi=sprintf("%-8g",$achi) || '---';
     $pchi=sprintf("%-8g",$pchi) || '---';
     $prms= ! $stats{$s}{phase_rms} ? '---' : sprintf("%-7.2f",$stats{$s}{phase_rms});
     $rrms= ! $stats{$s}{range_rms} ? '---' : sprintf("%-7.2f",$stats{$s}{range_rms});
     $qm_ep=$stats{$s}{percent_daily_qm_epochs} || '---';
     write;
     $k++;
  }
 #last if $st eq 'ALL';
}

sub ppp_stats {
   my $ac = shift;
   my $yyyy=shift;
   my $cal=shift;
   my $pdir="$par{PPP_DIR}/$ac/$yyyy/$cal";
   if ($archive) {
      $pdir="$par{PPP_DIR_ARCHIVE}/$ac/$yyyy/$cal";
   }
   opendir(my $dh,$pdir) or die "Couldn't open dir $pdir $!\n";
   my @sites= grep { /[a-z0-9_]{4}/ } readdir($dh);
   foreach my $s ( @sites ) {
      if ( $amb ) {
        next if ! exists $sn{$s};
      }
      summary_log_stats($sn{$s},"$pdir/$s/$cal.$s.summary.log");
   }
}

sub get_sites {
   my $field=shift;
   my $nmax=shift;
   my $rev = shift;
   my @sites= sort { $stats{$a}{$field} <=> $stats{$b}{$field} } keys %stats;
      @sites= reverse @sites if $rev;
   return  @sites[0..$nmax-1]
}

sub net_stats {
   my $proj=shift;
   my $ac=shift ;
   my $yyyy=shift;
   my $cal=shift;
   my $adir="$par{AMB_DIR}/$ac/$proj/$yyyy/$cal";
   if ($archive) {
      $adir="$par{AMB_DIR_ARCHIVE}/$ac/$proj/$yyyy/$cal";
   }
   opendir(my $dh , $adir) or die "Couldn't open dir $adir $!\n";
   my @nets =  grep { /[A-Z]/ } readdir($dh);
   foreach my $n ( @nets ) {
      summary_log_stats($n,"$adir/$n/$cal.$n.summary.log",'amb');   
   }
}
sub summary_log_stats {
   my $net=shift;
   my $f = shift;
   my $amb = shift || '';
   open(my $fh,'<',$f) or  return undef;
   my ($date,$pchi,$achi,$tslips,$s,@v,$max_qm_epochs,$decimate);
   my @f=qw( phase_rms 
             range_rms
             npts
             cycle_slips
             phase_outliers
             range_outliers
             dpos_ppp
             dpos_amb
             qm_interval
             qm_epochs
             qm_in_epochs
             rnx_interval
             rnx_sdate
             rnx_edate
            );
   if ( $amb ) {
     $f[3]='amb_cycle_slips';
   }            
   while(<$fh>) {
     if ( /SUMMARY FOR\s+:\s+([A-Z_0-9]+)\s+\|/ ) {
         $net=$1 if ! $net;
         next;
     }
     if ( /DATE\s+:\s+([0-9-\s]+)\|$/ ) {
        $date=$1;
        next;
     }
     if ( /SUMMARY FOR\s+(.*?)\s+DATE:\s+(.*)$/ ) {
        $net=$1 if ! $net;
        $date=$2;
        next;
     }
     if ( /AMB CHI-SQUARE\s+[=:]\s+(.*)$/ ) {
          $achi=$1 ;
          next;
     }
     if ( /PPP CHI-SQUARE\s+[=:]\s+(.*)$/ ) {
          $pchi=$1;
          next;
     }
     if ( /TOTAL CYCLE SLIPS\s+[=:](.*)$/ ) {
         $tslips=$1; 
         next;
     }
     s/^\s+//g;
     s/\s+$//g;
     s/^!.*$//g;
     s/^[\+\|].*$//;
     next unless length;
     @v=split(' ');
     $s=lc shift @v;
     $stats{$s}{net}=trim($net);
     $stats{$s}{amb_chi}= $achi;
     $stats{$s}{ppp_chi}= $pchi;
     #$stats{$s}{total_cycle_slips}=trim($tslips);
     @{$stats{$s}}{@f}=@v;
     $stats{$s}{percent_daily_qm_epochs} = 0;
     if ( $stats{$s}{rnx_interval} != 0 && $stats{$s}{qm_in_epochs} != 0 && $stats{$s}{qm_interval} != 0 ) {
       $decimate = sprintf("%d", $stats{$s}{qm_interval}/$stats{$s}{rnx_interval});
       $max_qm_epochs = $stats{$s}{qm_in_epochs}/$decimate if $decimate != 0;
       $stats{$s}{percent_daily_qm_epochs} = sprintf("%4.2f",$stats{$s}{qm_epochs}/$max_qm_epochs*100);
     }
   }
}

sub downloaded_rnx_stats {
   my $proj = shift;
   my $yyyy = shift;
   my $doy  = shift;
   my $rdir = "$par{RNX_DIR}/$yyyy/$doy";
   if ($archive) {
      $rdir = "$par{RNX_DIR_ARCHIVE}/$yyyy/$doy";
   }
   opendir(my $dh,$rdir) or die "Couldn't open $rdir $!\n";
   my @rnxs=grep { /\w{4}\d{4}\.\d{2}\w\.(z|bz2|gz|zip)$/i } readdir($dh);
   my %proj_sites=();
   @proj_sites{@psites}=@psites;
   my $ps=$pos->get;
   my $sv=$svec->get;
   my $rc=$rcvr->get;
   my $lc=$loc->loc;
   my $ii=$id->get;
   foreach my $r ( sort @rnxs ) {
      my $s = unpack 'a4',$r;
      next if ! exists $proj_sites{$s};
      my $S=uc $s;
      my $size= -s "$rdir/$r";
      $stats{$s}{net}=$sn{$s};
      $stats{$s}{rnx_size} = $size;
      $stats{$s}{'pos'} = exists $ps->{$S} ? 1 : 0 ;
      $stats{$s}{id} = exists $ii->{$S} ? 1 : 0 ;
      $stats{$s}{svec} = exists $sv->{$S} ? 1 : 0 ;
      $stats{$s}{rcvr} = exists $rc->{$S} ? 1 : 0 ;
      $stats{$s}{loc} = exists $lc->{$S} ? 1 : 0 ;
   }
   
}



sub usage {
  my $pod=Pod::Text::Termcap->new();
  $pod->parse_from_filehandle(man_page());
}

sub man_page {
my $man =qq(
=head1 NAME

$progname

Summarizes statistics from a daily run of Point Position or Ambiguities.
Output is to STDOUT.

=head1 USAGE

$progname -proj proj_name -date date [OPTIONS]

=head1 OPTIONS

=over 3

=item -ac [igs|jpl] (default:igs)

=item -orb [final|rapid] 

Orbit type for this processing.

=item -amb  

Set ambiguity run type to true

=item -ppp  

Set point position run type to true

=item -nmax 
       
Max. Number of fields to show for all the statistics.

=item -fields (field1,field2,..)
     
List of fields to show with up to nmax entries. 
The entries will be sorted in ascending order for the given field.
Possible field names are:
rms,chi,dpos,slips,qmepochs,rnxsize,pos,svec,id,loc,rcvr

=item -rfields (field1,field2,..)

Same as in -fields, but sorted descending order.

=back

=head1 EXAMPLES

To the summary of the processing for the project pbo-rapid 
show 20 entries with the largest dpos,chi and rms along with the 20
smallest rms. 

$progname -proj pbo-rapid -date 20090216 
          -fields rms 
          -rfields dpos,chi,rms -nmax 20 


=head1 AUTHOR

Victor Marcelo Santillan <marcelo\@geology.cwu.edu>

=head1 COPYRIGHT

Copyright \(c\) 2009 

Central Washington University

=cut
);
open(my $fh,"<",\$man ) or die "$!\n";
return $fh
}

