#!/usr/bin/perl
use FileHandle;
use File::Basename;
use Getopt::Long;
$cal = "-";
$noise = "-";
$dtype = "0";

GetOptions ('c' => \$cflg, 'n' => \$nflg, 's' => \$sflg, 't' => \$tflg);

if (($#ARGV + 1) < 4){die <<EOS;}
*** Preprocessing of Sentinel-1 TOPS SLC products, extract SLC data and generate SLC_tab ***
*** Copyright 2015, Gamma Remote Sensing, v1.4 8-Jun-2015 clw ***

usage: $0 <S1_list> <SLC_dir> <pol> <log>
  S1_list  (input) single column text file. Enteries are directories (including path) containing Sentinel-1 TOPS SLC products
  SLC_dir  directory for output SLC data files and SLC parameter files
           Note: output file names have the form : 20150119_iw1_hh.slc
  pol      SLC polarization to extract (hh,hv,vh,vv)
  log      (output) S1 SLC pre-processing log file
  -c       (option) apply radiometric calibration factor without noise subtraction
  -n       (option) apply radiometric calibration factor with noise subtraction
  -s       (option) output is SCOMPLEX format (default: FCOMPLEX)
  -t       (option) include full timestamp YYYYMMDDtHHMMSSin SLC and SLC_par filenames, default YYYYMMDD
EOS

$out_dir = $ARGV[1];
$pol = $ARGV[2];
$log = "$out_dir/$ARGV[3]";
print "S1 IW SLC product list: $ARGV[0]\n";
print "SLC output directory: $ARGV[1]\n";
print "Polarization: $pol\n";
print "log file: $log\n";

unless (-d $out_dir) {
  print "creating output directory for S1 IW SLC products: $out_dir\n";
  $exit = system("mkdir -p $out_dir");
  $exit == 0 or die "ERROR $0: non-zero exit status: mkdir -p $out_dir\n"
}

open(LOG,">$log") or die "ERROR $0: cannot open log file: $log\n";
LOG->autoflush;			#set filehandle special variable to flush output immediately
print LOG "$0 @ARGV\n\n";	#print command line that was used

$time = localtime;
print "PROCESSING START: $time\n";
print LOG "PROCESSING START: $time\n";
open(SLIST, "<$ARGV[0]") or die "ERROR $0: Sentinel list of product directories does not exist: $ARGV[0]\n";
if ($sflg) {
  $dtype = 1;
  print "output SLC format: SCOMPLEX\n";
}
else {
  print "output SLC format: FCOMPLEX\n";
}

LINE: while (<SLIST>) {		#read list of directories with unreformated SLC data
  chomp $_;
  next LINE if /^$/; 		#skip blank lines in input list
  next LINE if /^#/; 		#skip comments in the input list
  @fields = split;		#extract the identifier
  $path = $fields[0];

  @ann_files = glob "$path/annotation/s1a-iw?-slc-".$pol."*.xml";
  @tiff_files = glob "$path/measurement/s1a-iw?-slc-".$pol."*.tiff";
  @cal_files = glob "$path/annotation/calibration/calibration-s1a-iw?-slc-".$pol."*.xml";
  @noise_files = glob "$path/annotation/calibration/noise-s1a-iw?-slc-".$pol."*.xml";
  @tiff_iw1 = glob "$path/measurement/s1a-iw1-slc-".$pol."*.tiff";

  -e $tiff_iw1[0] or die "GeoTIFF missing: $path/measurement/s1a-iw1-slc-$pol*.tiff\n";
  my ($base, $dir1, $ext1) = fileparse($tiff_iw1[0], qr/\.[^.]*/); #extension is the last bit after the last period
  if($tflg) {
    $tstart = substr($base,15,15);
  }
  else {
    $tstart = substr($base,15,8);
  }
  printf("IW1 start timestamp: %s\n",$tstart);
  $SLC_tab = "$out_dir/../"."SLC_tab"."_".$tstart;
  print "SLC_tab: $SLC_tab\n";
  open(SLC_TAB,">$SLC_tab") or die "ERROR $0: cannot open SLC_tab file: $SLC_tab\n";

  print "\n*** S1 IW TOPS product directory files: $path\n";
  #print "Annotation:\n",join("\n", @ann_files);
  #print "\n\nMeasurement:\n",join("\n", @tiff_files);
  #print "\n\nCalibration:\n",join("\n", @cal_files);
  #print "\n\nNoise:\n",join("\n", @noise_files);
  #print "\n";

  foreach my $i (0 .. $#tiff_files){
    my ($base, $dir1, $ext1) = fileparse($tiff_files[$i], qr/\.[^.]*/); #extension is the last bit after the last period
    $beam = substr($base,4,3);
    if($tflg) {
      $tstart = substr($base,15,15);
    }
    else {
      $tstart = substr($base,15,8);
    }
    print "GeoTIFF:        $base$ext1\n";
    print "beam:           $beam\n";
    print "annotation XML: $ann_files[$i]\n";
    print "cal. LUT XML:   $cal_files[$i]\n";
    print "noise LUT XML:  $noise_files[$i]\n";
    $id = $tstart."_".$beam."_".$pol;
    $slc_par = "$out_dir"."\/".$id.".slc.par";
    $tops_par = "$out_dir"."\/".$id.".tops_par";
    $slc = "$out_dir"."\/".$id.".slc";
    print SLC_TAB "$slc  $slc_par  $tops_par\n";
    if ($cflg) {$cal = $cal_files[$i];}
    if ($nflg) {$noise = $noise_files[0]}
    print "SLC:         $slc\n";
    print "SLC_par:     $slc_par\n";
    print "TOPS_par:    $tops_par\n";
    execute("par_S1_SLC $tiff_files[$i] $ann_files[$i] $cal $noise $slc_par $slc $tops_par $dtype", $log);
    print "\n";
  }
  close SLC_TAB;
}

$time = localtime;
print "PROCESSING END: $time\n";
print LOG "PROCESSING END: $time\n";
exit 0;

sub extract_param{
  my ($infile,$keyword) = @_;
  open(PAR_IN,$infile) || die "ERROR $0: cannot open parameter file: $infile\n";

  while(<PAR_IN>){
    chomp;
    @tokens = split;
    if($tokens[0] eq $keyword){close PAR_IN; return @tokens;}
  }
  close PAR_IN;
  die "ERROR $0: keyword $keyword not found in file: $infile\n";
}

sub execute{
  my ($command, $log) = @_;
  print "$command\n";
  print LOG ("\n${command}\n");
  close LOG;
  $exit = system("$command 1>> $log 2>&1");
  $exit == 0 or die "ERROR $0: non-zero exit status: $command\n";
  if (-e $log){
    open(LOG,">>$log") or die "ERROR $0: cannot open log file: $log\n";
  }
  else {
    open(LOG,">$log") or die "ERROR : cannot open log file: $log\n";
  }
  LOG->autoflush;
}
