#!/usr/bin/perl
# Copyright © 2018, Bradley M. Kuhn
#   License: AGPL-3.0-or-later

# This script finds the most recent correspondence from the requestor, and
# sets the Due date out from that, based on the CLI input using Date::Manip

# should also add correspondence to note it wsa received.  Easiest way to send template?
use strict;
use warnings;

use autodie qw(:all);

use Getopt::Long;
use File::Spec;
use Date::Manip qw(ParseDate UnixDate);

my($VERBOSE, $INTERACTIVE, $RT_CMD, $SVN_CMD, $DUE_ADD, $DUE_DATE_FROM, $TICKET);
###############################################################################
sub FindDateOfMostRecentEmailBy ($@) {
  my($ticketSpec, @emails) = @_;
  my $ownSpecialEpoch = '1973-01-01';
  $ticketSpec =~ s%^\s*ticket\s*/\s*%%;
  open(my $rtShowFH, "-|", "$RT_CMD", "show", $ticketSpec);
  my $latestDate = $ownSpecialEpoch;
  foreach my $email (@emails) {
    while (my $showLine = <$rtShowFH>) {
      print STDERR "rt show line for $ticketSpec: $showLine" if ($VERBOSE >= 10);
      if ($showLine =~ /^.+\s+by\s+$email\s+on\s+(.+)$/) {
        my($fullDate) = $1;
        my $curDate = ParseDate($fullDate);
        die "'rt show' line, \"$showLine\" matches as if it were a comment/correspondence line but has an unprocessable date of \"$fullDate\""
          unless defined $curDate;
        $latestDate = $curDate if ($latestDate lt $curDate);
      }
    }
  }
  close $rtShowFH;
  die("No correspondence/comment of any kind found for \"" . join(", ", @emails) .
      "\" in \"$ticketSpec\"")
    if $latestDate eq $ownSpecialEpoch;
  return $latestDate;
}
###############################################################################
sub RequestorsForTicket ($) {
  my($ticketSpec) = @_;
  $ticketSpec =~ s%^\s*ticket\s*/\s*%%;
  my @requestors;
  open(my $rtShowFH, "-|", "$RT_CMD", "show", '-s', $ticketSpec);
  while (my $showLine = <$rtShowFH>) {
    print STDERR "rt show line for $ticketSpec: $showLine" if ($VERBOSE >= 10);
    if ($showLine =~ /^\s*Requestors\s*:\s+(.+)$/) {
      my $emails = $1;
      @requestors = split(/\s*,\s*/, $emails);
      last;
    }
  }
  close $rtShowFH;
  return @requestors;
}
###############################################################################

GetOptions("verbose=i" => \$VERBOSE, "interactive" => \$INTERACTIVE,
           "rtCommand=s" => \$RT_CMD, "svnCommand=s" => \$SVN_CMD,
           "dueAdd=s" => \$DUE_ADD, "dueDateFrom" => \$DUE_DATE_FROM,
           "ticket=i" => \$TICKET);

$RT_CMD = '/usr/bin/rt' unless defined $RT_CMD;
$SVN_CMD = '/usr/bin/svn' unless defined $SVN_CMD;

$INTERACTIVE = 0 if not defined $INTERACTIVE;

unless (defined $TICKET) {
  print STDERR "--ticket <ID> where <ID> is a valid ticket is required\n";
  exit 1;

}
unless (defined $DUE_ADD) {
  print STDERR "--dueAdd <STRING> where <STRING> is a valid datetime is required\n";
  exit 1;
}

my(@requestors) = RequestorsForTicket($TICKET);

if (@requestors <= 0) {
  print STDERR "No requestors found for $TICKET, giving up.\n";
  exit 1;
}
my $lastDate = FindDateOfMostRecentEmailBy($TICKET, @requestors);
my $forwardDate = DateCalc($lastDate, $DUE_ADD);
print UnixDate($forwardDate, "%Y-%m-%d %H:%M %z");

###############################################################################
#
# Local variables:
# compile-command: "perl -c rt-set-deadline-from-last-correspondence.plx"
# perl-indent-level: 2
# End: