#!/usr/bin/perl -w

# This script uses aqtalarmtally.pl to generate alarm reports
# for recently received Aquarius telemetry files.  The reports
# get sent via email to the folks who care about such things.
# Some effort is made to avoid sending duplicate reports.

# Norman Kuring		31-Mar-2011	Initial development
# Norman Kuring		 1-Apr-2011	Check the most recent 20 files instead
#					of just 5.
# Norman Kuring		29-Jun-2011	Send notifications to aqopstxt list
#					of cell-phone numbers.
# Norman Kuring		31-Aug-2011	Make allowances for quicklook (QL)
#					files and for Service Platform
#					telemetry monitoring.
# Norman Kuring		15-Dec-2011	Ignore downlink times when comparing
#					report files.  This should reduce
#					the number of automated alarm
#					notifications a bit.  Incompletely
#					overlapping L1A files will still
#					generate separate notifications for the
#					same event.
# Norman Kuring		23-Apr-2012	Fix file-selection regular expression
#					to also collect SOFTWARE message files.

use strict;

my $dir = '/web/data/Aquarius/DOWNLINKS/L1';

# Step through the directories in reverse chronological order
# until I find the 20 most recent L1A time periods.
my @l1a;
YEAR:
foreach my $y (reverse read_dir($dir,'^\d{4}$')){
  foreach my $mmdd (reverse read_dir("$dir/$y",'^\d{4}$')){

    my @f =
    read_dir(
    "$dir/$y/$mmdd",
    '^Q\d{8}_\d{6}_T\d{8}_\d{6}_\d{8}_\d{6}\.AQ_L1A(?:QL)?\.txt$'
    );

    while(my $f = pop @f){
      my $basename = $f;
      $basename =~ s/\.AQ_L1A(?:QL)?\.txt$//;
      my $pat = $f;
      $pat =~ s/\./\\./g;
      $pat =~ s/L1A(?:QL)?/(?:L1A(?:QL)?\\.(?:AQ|SP)_)?\\w+/;
      $pat = "^$pat\$";
      push @l1a,["$dir/$y/$mmdd",$pat,$basename];
      last YEAR if @l1a == 20;
    }
  }
}

# Make a list of telemetry files that are
# available for each of the 20 time periods,
# and use the list to generate an alarm report
# for each of the periods.
my $alarmtally = '/web/aquarius/scripts/aqtalarmtally.pl';
my $repdir = '/web/aquarius/metadata/alarms/reports';
foreach my $dp (@l1a){
  my @f = map "$dp->[0]/$_\n", grep !/\.AQ_L1A(?:QL)?\.txt$/,
          read_dir(@$dp[0,1]);
  my $out = "$repdir/$dp->[2].txt";
  my $cmd = "$alarmtally > $out.new";
  open P,'|-',$cmd or die "Could not open pipe to $cmd ($!)";
  print P @f;
  close P or die "Error executing $cmd ($!)";

  if(-z "$out.new"){
    # No report was generated.
    unlink "$out.new";
    next;
  }

  # Find all previous reports having the same start and stop
  # times, but ignoring the downlink time.
  my $pat = "$dp->[2].txt";
  $pat =~ s/\./\\./g;
  $pat =~ s/^Q\d{8}_\d{6}/Q\\d{8}_\\d{6}/;
  $pat = "^$pat\$";
  my @reports = read_dir($repdir,$pat);

  if(@reports){
    # A report for this time period was created earlier.  Send it out
    # only if there are differences from the most recent previous version.
    my $most_recent = (sort {-M $a <=> -M $b} map "$repdir/$_",@reports)[0];
    if( diff("$out.new", $most_recent) ){
      rename "$out.new", $out;
      sendmail($out);
    }
    else{
      unlink "$out.new";
    }
  }
  else{
    rename "$out.new", $out;
    sendmail($out);
  }
}


sub sendmail{
  # Send the report via email.
  my $recipients = 'aqops@seawifs.gsfc.nasa.gov';
  my $dnr = 'NoReply@aquarius.nasa.gov';
  my $sendmail = "/usr/lib/sendmail -f$dnr -t";
  my $f = shift;
  open F,'<',$f or die "Could not open $f ($!)";
  local($/) = undef;
  my $report = <F>;
  close F;
  $f = (split /\//,$f)[-1];	# Get rid of the path; just keep the file name.
  open P,'|-',$sendmail or die "Could not open pipe to $sendmail ($!)";
  print P
  "From: $dnr\n",
  "To: $recipients\n",
  "Subject: Aquarius telemetry alarms: $f\n",
  $report;
  close P or die "Error executing $sendmail ($!)";

  # Send a corresponding brief notification message to cell-phone list.
  $recipients = 'aqopstxt@seawifs.gsfc.nasa.gov';
  my ($tstr) = $report =~ /Q\d{8}_\d{6}_T(\d{8}_\d{6}_\d{8}_\d{6})\./;
  substr($tstr,15,1) = '-';
  open P,'|-',$sendmail or die "Could not open pipe to $sendmail ($!)";
  print P
  "From: $dnr\n",
  "To: $recipients\n",
  "Subject: Aquarius anomaly report\n\n",
  "For period: $tstr\n",
  "Details in email.\n";
  close P or die "Error executing $sendmail ($!)";
}

sub diff{
  my ($f,$g) = @_;
  -s $f == -s $g or return 1;
  open F,$f or die "Could not open $f ($!)";
  open G,$g or die "Could not open $g ($!)";
  local($/) = undef;
  my $ff = <F>;
  my $gg = <G>;
  close F;
  close G;

  # The boundary strings will always be different, so eliminate them.
  my ($fb) = $ff =~ /boundary="([^"]+)"/;
  my ($gb) = $gg =~ /boundary="([^"]+)"/;
  $ff =~ s/$fb//g;
  $gg =~ s/$gb//g;

  # The downlink times in the filenames may be different, but we
  # don't care about that either.
  $ff =~ s/Q\d{8}_\d{6}_T//g;
  $gg =~ s/Q\d{8}_\d{6}_T//g;

  if($ff eq $gg){
    return 0;	# The files are the same.
  }
  else{
    return 1;	# The files are different.
  }
}

sub read_dir{
  my ($dir,$pattern) = @_;
  opendir D,$dir or die "Could not open $dir ($!)";
  my @results = sort grep /$pattern/, readdir D;
  closedir D;
  @results;
}
