#!/usr/bin/perl
#
# List atq jobs, ordered by datetime and with subject, where found.
#
# Requires: libcapture-tiny-perl libdatetime-perl
#   libdatetime-format-strptime-perl.

use English qw(-no_match_vars);
use common::sense;
use Capture::Tiny qw( capture );
use DateTime;
use DateTime::Format::Strptime;
use File::Slurp;

# Prepare timezone and formatter to use for each job we list.
chop(my $tz = read_file('/etc/timezone'));
my $dt_formatter = DateTime::Format::Strptime->new(pattern => "%b %e %a %R %Z");

# Look for the given job's subject and return it if found.
sub acquire_subject {
   my ($jobnum) = @_;
   my ($stdout, $stderr, $exit) = capture { system("at -c $jobnum"); };
   die($stderr) if ($exit);

   # If the job came from my email-at script, it will have an
   # environment variable for the subject.
   my ($subject) =
      $stdout =~ m/^XAT_Subject=(.+); export XAT_Subject$/m;
   # Unescape.
   $subject =~ s/\\//g;
   return $subject // '?';
}

# Given an 'lsat' item, return it in a more human-readable form.
sub transform {
   my ($job_uid_filename) = @_;

   # $job_uid_filename is a string in the form "<uid> <file name>".
   # E.g. "1000 a0028f0194a510".
   my ($uid, $filename) = split(' ', $job_uid_filename);

   # The file name encodes things, byte offset + thing pairs follow:
   # 0 'at' queue name, e.g. "a"
   # 1 hex entry number within queue, e.g. 0028f.
   # 6 hex epoch time in minutes, e.g. 0194a510.
   #
   my ($queue, $xnum, $xepoch_m) = (
      substr($filename, 0, 1),
      substr($filename, 1, 5),
      substr($filename, 6),
   );
   my ($jobnum, $epoch_s) = (hex($xnum), 60 * hex($xepoch_m));
   my $subject = acquire_subject($jobnum);
   my $t = DateTime
      ->from_epoch(epoch => $epoch_s)
      ->set_formatter($dt_formatter)
      ->set_time_zone($tz);
   return [ $t, $jobnum, $subject ];
}

my ($stdout, $stderr, $exit) = capture { system("lsat"); };
die($stderr) if ($exit);
my @jobs = split(/\n/, $stdout);
my @transformed = sort { $a->[0] <=> $b->[0] } map(transform($_), @jobs);
printf("%s %d %s\n", @$_) foreach (@transformed);

exit(0);
