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

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, %AMOUNTS, $SHOW_AMOUNTS, $QUERY_STRING, $SUB_TOTALS);

###############################################################################
sub TicketIDsReadyForPayment () {
  my @ticketSpecs;
  my $queryString = $QUERY_STRING;

  if (not defined $queryString or $queryString =~ /^\s*$/) {
    $queryString = "Status = 'ready-for-payment' and Owner = 'bkuhn' and Queue = 'outreachy-interns' and Subject like '%2019-12%'";
    $queryString = "Status = 'ready-for-payment' and Owner = 'bkuhn' and Due < '2020-04-30'";
    $queryString =  "Status = 'ready-for-payment'";
    $queryString = "Status = 'ready-for-payment' and 'CF.{payment-method}' = 'USD PayPal'";
    $queryString = "Status = 'ready-for-payment'";
  }
  print "Using $queryString\n";
  open(my $rtLsFH, "-|", "$RT_CMD", "ls", "-i", $queryString);
  print "Running: rt ls -i $queryString\n" if ($VERBOSE >= 10);
  while (my $lsLine = <$rtLsFH>) {
    print "rt ls line from Ready for payment search: $lsLine" if ($VERBOSE >= 10);
    chomp $lsLine;
    next if $lsLine =~ /^\s*$/;   # There are sometimes blank lines in the rt ls -i output,
    push(@ticketSpecs, $lsLine);  # particularly with 0 results, and no empty strings go on this list
  }
  print "Done: rt ls -i Status=ready-for-payment\n" if ($VERBOSE >= 10);
  close $rtLsFH;
  return @ticketSpecs;
}
###############################################################################
sub FindMostRecentPaymentMethodForTicket ($) {
  my($ticketSpec) = @_;
  my $paymentMethod;
  $ticketSpec =~ s%^\s*ticket\s*/\s*%%;
  open(my $rtShowFH, "-|", "$RT_CMD", "show", '-t', 'ticket', '-f', 'CF.{payment-method}', $ticketSpec);
  my($ticketDataAgain, $value) = <$rtShowFH>;
  close $rtShowFH;
  chomp $value; $value =~ s/^\s*cf.\{payment-method\}\s*:\s+(.*)$/$1/i
    or warn "$ticketSpec: Unknown value for payment-method of \"$value\"";

  if (not defined $value or $value =~ /^\s*$/) {
    $value = "NO-CF-SET";
  }
  if ($SHOW_AMOUNTS) {
    open(my $rtShowFH, "-|", "$RT_CMD", "show", '-t', 'ticket', '-f', 'CF.{payment-amount}', $ticketSpec);
    my($ticketDataYetAgain, $curAndAmount) = <$rtShowFH>;
    close $rtShowFH;
    chomp $curAndAmount; $curAndAmount =~ s/^\s*cf.\{payment-amount\}\s*:\s+(.*)$/$1/i;
    $ticketSpec =~ s%^\s*ticket\s*/\s*%%;
    $curAndAmount = "USD -32767.69" if not defined $curAndAmount;
    if ($curAndAmount
        =~ /^\s*([A-Z]{3,3})\s+([\-\d\,\.]+)(\s+\(\s*\$\s*[\-\d\,\.]+\s*\))?\s*$/) {
      ($AMOUNTS{$ticketSpec}{currency}, $AMOUNTS{$ticketSpec}{amount}) = ($1, $2);
      $AMOUNTS{$ticketSpec}{amount} = $3 unless defined $AMOUNTS{$ticketSpec}{amount};
    } elsif ($curAndAmount
        =~ /^\s*([\-\d\,\.]+)(\s+\(\s*\$\s*[\-\d\,\.]+\s*\))?\s+([A-Z]{3,3})\s*$/) {
      ($AMOUNTS{$ticketSpec}{amount}, $AMOUNTS{$ticketSpec}{currency}) = ($1, $3);
      $AMOUNTS{$ticketSpec}{amount} = $2 unless defined $AMOUNTS{$ticketSpec}{amount};
  } else {
    die "Ticket, $ticketSpec, has amount of $curAndAmount";
  }
    $AMOUNTS{$ticketSpec}{amount} =~ s/\$//g; $AMOUNTS{$ticketSpec}{amount} =~ s/,//g;
    $AMOUNTS{$ticketSpec}{currency} =~ s/\s//g;
  }
  return $value;
}
###############################################################################
sub GetStatusOfTicket ($) {
  my($ticketSpec) = @_;
  my $paymentMethod;
  $ticketSpec =~ s%^\s*ticket\s*/\s*%%;
  open(my $rtShowFH, "-|", "$RT_CMD", "show", '-t', 'ticket', '-f', 'status', $ticketSpec);
  my($ticketDataAgain, $value) = <$rtShowFH>;
  close $rtShowFH;
  chomp $value; $value =~ s/^\s*Status\s*:\s+(.*)$/$1/i
    or warn "$ticketSpec: Unknown value for Status of \"$value\"";

  if (not defined $value or $value =~ /^\s*$/) {
    $value = "MISSING-TICKET-STATUS";
  }
  return $value;
}
###############################################################################

GetOptions("verbose=i" => \$VERBOSE, "interactive" => \$INTERACTIVE, 'showAmounts' => \$SHOW_AMOUNTS,
           'subTotals' => \$SUB_TOTALS,
           "rtCommand=s" => \$RT_CMD, "svnCommand=s" => \$SVN_CMD, 'queryString=s' => \$QUERY_STRING);
$SHOW_AMOUNTS = 1 if $SUB_TOTALS;

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

$INTERACTIVE = 0 if not defined $INTERACTIVE;

my @ticketSpecs = TicketIDsReadyForPayment();

if (@ticketSpecs <= 0) {
  print "No tickets found that are ready for payment at this time\n";
  exit 0;
}

my %payments;

print "Total tickets ready for payment is: ", scalar(@ticketSpecs), "\n\n";
foreach my $ticketSpec (@ticketSpecs) {
  my $paymentMethod = FindMostRecentPaymentMethodForTicket($ticketSpec);
  print STDERR "$ticketSpec has payment method of $paymentMethod\n" if ($VERBOSE > 6);
  if (not defined $paymentMethod) {
    warn "Cannot find payment method for ticket, $ticketSpec";
    $paymentMethod = "UNKNOWN PAYMENT METHOD";
  }
  push(@{$payments{$paymentMethod}}, $ticketSpec);
}
print "#" x 70, "\n";
my  $overallTotalOk =  1;
my %overallTotals;
foreach my $paymentMethod (sort { $a cmp $b } keys %payments) {
  print "$paymentMethod: Count: ", scalar(@{$payments{$paymentMethod}}), "\n";
  print "     Tickets: ", join(" ", map { s%^\s*ticket\s*/\s*%%; $_; } @{$payments{$paymentMethod}}), "\n";
  my $subTotalOk = 1;
  my %subTotals;
  if ($SUB_TOTALS) {
    foreach my $tix (@{$payments{$paymentMethod}}) {
      $tix =~ s%^\s*ticket\s*/\s*%%;
      my($currency, $val) = ($AMOUNTS{$tix}{currency}, $AMOUNTS{$tix}{amount});
      $subTotals{$currency} = 0.00 unless defined $subTotals{$currency};
      my $status = GetStatusOfTicket($tix);
      print sprintf("     %5d: %8.2f %3.3s", $tix, $val, $currency), ( ($status eq 'ready-for-payment') ? "\n" : " ($status)\n");
      if (defined $val and $val =~ /^[\d\.]+$/) { $subTotals{$currency} += $val;  } else { $subTotalOk = 0; }
    }
    if ($subTotalOk) {
      print sprintf("%30s", "SUBTOTAL for $paymentMethod\n");
      foreach my $currency (keys %subTotals) {
        print sprintf("%30s %.2f %3.3s\n\n", " ", $subTotals{$currency}, $currency);
        $overallTotals{$currency} = 0.00 unless defined $overallTotals{$currency};
        $overallTotals{$currency} += $subTotals{$currency};
      }
    } else {
      $overallTotalOk = 0;
    }
  }
}
if ($SHOW_AMOUNTS and not $SUB_TOTALS) {
  print "Unable to find amounts for all tickets\n"  if (scalar(@ticketSpecs) != scalar(keys %AMOUNTS));
  foreach my $tix (sort { $a <=> $b} (keys %AMOUNTS)) {
    foreach my $currency (keys %overallTotals) {
      my $val = $AMOUNTS{$tix}{$currency};
      my $status = GetStatusOfTicket($tix);
      print sprintf("     %5d: %8.2f %3.3s", $tix, $val, $currency), ( ($status eq 'ready-for-payment') ? "\n" : " ($status)\n");
      $overallTotals{$currency} = 0.00 unless defined $overallTotals{$currency};
      if ($val =~ /^[\d\.]+$/) { $overallTotals{$currency} += $val;  } else { $overallTotalOk = 0; }
    }
  }
}
if ($overallTotalOk and $SHOW_AMOUNTS) {
  print sprintf("%30s:\n", "TOTAL AMOUNT");
  foreach my $currency (keys %overallTotals) {
    print sprintf("%30s %.2f %3.3s\n\n", " ", $overallTotals{$currency}, $currency);
  }
}
###############################################################################
#
# Local variables:
# compile-command: "perl -c rt-bulk-prep-pay.plx"
# perl-indent-level: 2
# End: