#!/usr/bin/perl -w
use strict;
=explain
---------------------------------------------------------------------
  usage: chmod +x sdmintentmods.pl; sdmintentmods.pl <SDMdir>
---------------------------------------------------------------------
Lorant Sjouwerman (lsjouwer@nrao.edu) - originated 01FEB2017 for NRAO
---------------------------------------------------------------------
This perl script takes the SDM directory name and echoes scan intents
Then it offers to change intents on a per scan basis and rewrites the
Scan.xml file (after backing up) or leaves a Scan.xml_datetime in the
directory (to check differences and/or apply/rename at a later date).
---------------------------------------------------------------------
20170201, Ver 1.0, Lorant @NRAO
20170407, Ver 1.1, Lorant @NRAO: Added some more polarization intents
=cut

#####################################################################

die " USAGE\: sdmintentmods\.pl \<SDMdir\>\n" if ($#ARGV != 0);

#####################################################################
my$dati = `date +%Y%m%d%H%M`; chomp($dati);
my$scans="$ARGV[0]/Scan\.xml";
my$bakup="$scans\.org";
#my$scans="$ARGV[0]/tempscan\.xml";
my$result="$scans\_$dati";
my$swap="$scans\_$dati\_swap";
my(@line, @row0,@row1,@row2,@row3,@row4,@row5,@row6,@row7,@row8,@row9,@mods);
my($i, $j, $k, $s, $f, $b, $c, $t) = (0,0,0,0,0,0,0,0);
my($tot, $sel, $io, $sin, $org);
die " NO SUCH FILE $scans\: DIE" if (! -s $scans);
my@opts = ("OBSERVE\_TARGET","SYSTEM\_CONFIGURATION","CALIBRATE\_FLUX","CALIBRATE\_BANDPASS","CALIBRATE\_PHASE","CALIBRATE\_AMPLI","CALIBRATE\_POLARIZATION","CALIBRATE\_POL\_LEAKAGE","CALIBRATE\_POL\_ANGLE","CALIBRATE\_DELAY","CALIBRATE\_POINTING","UNSPECIFIED");

open FIL, "$scans" or die "Cannot open $scans";
while (<FIL>) {
  $line[$i] = $_;
  $s ++ if (m/SYSTEM_CONFIGURATION/);
  $f ++ if (m/CALIBRATE\_FLUX/);
  $b ++ if (m/CALIBRATE\_BANDPASS/);
  $c ++ if (m/CALIBRATE\_/);
  $t ++ if (m/OBSERVE\_TARGET/);
  $i++;
}
close FIL;
$tot = `wc -l $scans|cut -f1 -d" "`;
if (! -e "$bakup") {
  open FIL, ">$bakup" or die "Cannot write $bakup";
  print FIL @line;
  close FIL;
  chmod(0666,$bakup);
}
#print "$tot\n$line[$i-1]";
printf "Read %u of %u lines \(%u%%\) in %s\n", $i, $tot, 100*$i/$tot, $scans;
printf "  % 3u scans include a TARGET intent and\n  % 3u scans include a CALIBRATE intent\: ", $t, $c;
printf "%u\/%u contain FLUX\/BANDPASS \(\& %u SYSTEM\)\n", $f, $b, $s;

$sel = "c";
while ($sel !~ m/[ACQT]/) {
  printf "\> List target\, calibrator or all scans \(enter t\, c or a\; q to exit\)\? ";
  printf "\[c\] " if ($sel eq "c");
  $io = <STDIN>; chomp($io);
  $io = "q" if ($io =~ m/0/);
  $sel = $io if ($io =~ m/[\w]/);
  $sel = uc($sel);
}
exit(0) if ($sel eq "Q");
#####################################################################
$i=0;
while (defined $line[$i]) {
  last if ($line[$i] =~ m +\<\/ScanTable\>+);
  if ($line[$i] =~ m + \<row\>+) {
    $i++;
# instead of split can also match between > and < and only lines that change
    $row0[$j] = (split /\</, (split /\>/, $line[$i])[1])[0];  # scanNumber
#    $row1[$j] = $line[$i+1];                                  # startTime
#    $row2[$j] = $line[$i+2];                                  # endTime
    $row3[$j] = (split /\</, (split /\>/, $line[$i+3])[1])[0];# numIntent   -mod
#    $row4[$j] = $line[$i+4];                                  # numSubscan
    $row5[$j] = (split /\</, (split /\>/, $line[$i+5])[1])[0];# scanIntent  -mod
    $sin = $row5[$j];
    $sin =~ s/\_CONFIGURATION//g;
    $sin =~ s/CALIBRATE\_//g;
    $sin =~ s/AMPLI/AMPLITUDE/;
    $row6[$j] = (split /\</, (split /\>/, $line[$i+6])[1])[0];# calDataType -mod
    $row7[$j] = (split /\</, (split /\>/, $line[$i+7])[1])[0];# cal..OnLine -mod
    $row8[$j] = (split /\</, (split /\>/, $line[$i+8])[1])[0];# sourceName
#    $row9[$j] = $line[$i+9];                                  # execBlockId
    $org = sprintf "Scan \#% 4i\:% 15s\: $sin\n", $row0[$j], $row8[$j];
    if ($sel =~ m/[CT]/) {
      if ($sel =~ m/T/) {
        printf "$org" if ($row5[$j] =~ /TAR/);
      } else {
        printf "$org" if (($row5[$j]=~/CAL/)||(($row5[$j]=~/SYS/)||($row5[$j]=~/UNS/)));
      }
    } else {
      printf "$org";
    }
    $j++;
    $i += 10;
  }
  $i++;
}

$sel = -1;
while ($sel < 0) {
  printf "\> Enter scan number to modify \(or 0 when done\) \: ";
  $sel = <STDIN>; chomp($sel);
  $sel = 0 if (uc($sel) =~ m/Q/);
  if ($sel > 0) {
# sel = scan no, j is row idx, io is operation mode, mods lists modified scans
    $mods[$k] = $sel;
    $j = $sel - 1;
    my@intents = (split /\s+/, $row5[$j]);
    my($old,$new);
    $org = 2;
    while (defined $intents[$org]) {
      printf "  \- found intent \(%u\) $intents[$org]\n", $org-1;
      $org++;
    }
    
    $io = "0";
    until ($io =~ m/[ADRQ]/) {
      printf "\> Add\, delete\, or replace intent \(enter a\, d or r\; q to skip\)\? ";
      $io = <STDIN>; chomp($io);
      $io = "Q" if ($io =~ m/0/);
      $io = uc($io) if ($io =~ m/[adrq]/);
    }
#####################################################################
    if ($io eq "A") {
      my$idx=0;
      while (defined $opts[$idx]) {
        printf "  %u %s\n", $idx+1, $opts[$idx];
        $idx++;
      }
      $new=0;
      while (($new < 1) || ($new > ($idx))) {
        printf "\> Which intent number to add to the scan \(select number\) \? ";
        $new = <STDIN>; chomp ($new);
      }
      printf "Scan $sel\: adding %s intent\n", $opts[$new-1];
      $row3[$j] ++;
#      $row5[$j] = sprintf "        \<scanIntent\>%u %u", $intents[0], $intents[1]+1;
      $row5[$j] = sprintf "%u %u", $intents[0], $intents[1]+1;
      $old=2;
      while (defined $intents[$old]) {
	 $row5[$j] = sprintf "$row5[$j] %s", $intents[$old];
         $old++;
      }
#      $row5[$j] = sprintf "$row5[$j] %s\<\/scanIntent\>\n", $opts[$new-1];
      $row5[$j] = sprintf "$row5[$j] %s", $opts[$new-1];

      my@flds = (split /\s+/, $row6[$j]);
      $flds[1] ++;
      push @flds, "NONE";
      $row6[$j] = sprintf "@flds";
      @flds = (split /\s+/, $row7[$j]);
      $flds[1] ++;
      push @flds, "false";
      $row7[$j] = sprintf "@flds";
    }
#####################################################################
    if ($io eq "R") {
      $old=0;
      while (($old < 1) || ($old > ($org-2))) {
        printf "\> Which intent number to replace \(see number above\) \? ";
        $old = <STDIN>; chomp ($old);
      }
      my$idx=0;
      while (defined $opts[$idx]) {
        printf "  %u %s\n", $idx+1, $opts[$idx];
        $idx++;
      }
      $new=0;
      while (($new < 1) || ($new > ($idx))) {
        printf "\> Which intent number to replace with \(select number\) \? ";
        $new = <STDIN>; chomp ($new);
      }
      printf "Scan $sel\: replacing %s with %s intent\n", $intents[$old+1], $opts[$new-1];
      $row5[$j] =~ s/$intents[$old+1]/$opts[$new-1]/;
    }
#####################################################################
    if ($io eq "D") {
      if ($intents[1] < ($org-1)){
        my$idx=0;
        $old=0;
        while (($old < 1) || ($old > ($org-2))) {
          printf "\> Which intent number to delete from the scan \(see number above\) \? ";
          $old = <STDIN>; chomp ($old);
        }
        my$skip = $intents[$old+1];
        printf "Scan $sel\: deleting %s intent\n", $skip;
        $row3[$j] --;
#        $row5[$j] = sprintf "        \<scanIntent\>%u %u", $intents[0], $intents[1]+1;
        $row5[$j] = sprintf "%u %u", $intents[0], $intents[1]-1;
        $old=2;
        while (defined $intents[$old]) {
          $row5[$j] = sprintf "$row5[$j] %s", $intents[$old] if ($intents[$old] !~ /$skip/);
          $old++;
        }
#        $row5[$j] = sprintf "$row5[$j] %s\<\/scanIntent\>\n", $opts[$old-1];
        my@flds = (split /\s+/, $row6[$j]);
        $flds[1] --;
        pop @flds;
        $row6[$j] = sprintf "@flds";
        @flds = (split /\s+/, $row7[$j]);
        $flds[1] --;
        pop @flds;
        $row7[$j] = sprintf "@flds";
      } else {
        print "  NOTE\: cannot delete a single scan intent\, add one first\, try again\!\n";
      }
    }
#####################################################################
    $sel = -1;
  }
  $k++;
  
}
my@temp = sort(@mods);
printf "  Scan numbers to be modified\: @temp\n";
$k = @mods;
for ($j=0; $j<$k; $j++) {
  for ($i=0; $i<$tot; $i++) {
    if ($line[$i] =~ /\<scanNumber\>$mods[$j]\<\/scanNumber\>/) {
      $line[$i+3] = "        \<numIntent\>$row3[$mods[$j]-1]\<\/numIntent\>\n";
      $line[$i+5] = "        \<scanIntent\>$row5[$mods[$j]-1]\<\/scanIntent\>\n";
      $line[$i+6] = "        \<calDataType\>$row6[$mods[$j]-1]\<\/calDataType\>\n";
      $line[$i+7] = "        \<calibrationOnLine\>$row7[$mods[$j]-1]\<\/calibrationOnLine\>\n";
      $i += 10;
    }
  }
}

open FIL, ">$result" or die "Cannot write $result";
print FIL @line;
close FIL;
chmod(0666,$scans,$result);

$sel = "n";
while ($sel !~ m/[NY]/) {
  printf "\> Apply these changes \(enter y or n\)\? ";
  printf "\[n\] " if ($sel eq "n");
  $io = <STDIN>; chomp($io);
  $sel = $io if ($io =~ m/[\w]/);
  $sel = uc($sel);
}
if ($sel eq "Y") {
  rename($scans,$swap);
  rename($result,$scans);
  $result .= "\.old";
  rename($swap,$result);
}

exit(0);

