#!/usr/bin/env perl
#===============================================================================
#
#         FILE: resume_workflow
#
#        USAGE: ./resume_workflow epno
#
#  DESCRIPTION: For use with an HPR show that may not be fully processed.
#               Determines which workflow step is the next that needs to be
#               run, displays what it is and the script needed to perform it,
#               and passes the script name to the caller.
#
#      OPTIONS: ---
# REQUIREMENTS: ---
#         BUGS: ---
#        NOTES: ---
#       AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com
#      VERSION: 0.0.2
#      CREATED: 2024-02-10 17:53:09
#     REVISION: 2024-03-10 19:15:14
#
#===============================================================================

use v5.16;
use strict;
use warnings;
use feature qw{ postderef say signatures state try };
no warnings
    qw{ experimental::postderef experimental::signatures experimental::try };

use Config::General;

use List::Util      qw( maxstr minstr );
use List::MoreUtils qw( uniq );
use File::Slurper   qw( read_text read_lines );
use JSON;

use Log::Handler;

use Data::Dumper;

#
# Version number (Incremented by Vim)
#
our $VERSION = '0.0.2';

#
# Script and directory names
#
( my $PROG = $0 ) =~ s|.*/||mx;
( my $DIR  = $0 ) =~ s|/?[^/]*$||mx;
$DIR = '.' unless $DIR;

#-------------------------------------------------------------------------------
# Declarations
#-------------------------------------------------------------------------------
#
# Constants and other declarations
#
my $basedir      = "$ENV{HOME}/HPR/Show_Submission";
my $cache        = "$basedir/shownotes";
my $logs         = "$basedir/logs";
my $logfile      = "$logs/$PROG.log";
my $j_shownotes  = 'shownotes.json';

my $formatfile  = '.format';
my $statusfile  = '.status';
my $assetfile   = '.assets';
my $picturefile = '.pictures';

#
# Setting the environment variable 'resume_workflow_DEBUG' to greater than
# 0 enables debug output. Different values control different output
#
my $DEBUG = 0;
my $DEBUG_env = "${PROG}_DEBUG";
if ( defined($ENV{"$DEBUG_env"})) {
    $DEBUG = $ENV{"$DEBUG_env"};
}

my ($showno, $showid, $missed);

my %showdata;
my @statustags = qw(
    copied
    parsed
    format
    metadata
    pictures
    assets
    edited
    converted
    rendered
    uploaded
    database
    reported
);

#
# Set up the tag hash
#
# {{{
my %taghash = (
    'copied' => {
        'description' => 'Copy notes',
        'script'      => 'copy_shownotes',
        'level'       => 1,
    },
    'parsed' => {
        'description' => 'Parse raw',
        'script'      => 'do_parse',
        'level'       => 1,
    },
    'format' => {
        'description' => 'Change format',
        'script'      => 'do_change_format',
        'level'       => 2,
    },
    'metadata' => {
        'description' => 'Edit metadata',
        'script'      => 'do_edit_shownotes',
        'level'       => 2,
    },
    'pictures' => {
        'description' => 'Process pictures',
        'script'      => 'do_pictures',
        'level'       => 2,
    },
    'assets' => {
        'description' => 'Upload assets',
        'script'      => 'do_asset_upload',
        'level'       => 2,
    },
    'edited' => {
        'description' => 'Edit notes',
        'script'      => 'do_vim',
        'level'       => 1,
    },
    'converted' => {
        'description' => 'Run Pandoc',
        'script'      => 'do_pandoc',
        'level'       => 1,
    },
    'rendered' => {
        'description' => 'Run browser',
        'script'      => 'do_browse',
        'level'       => 1,
    },
    'uploaded' => {
        'description' => 'Upload HTML',
        'script'      => 'do_upload',
        'level'       => 1,
    },
    'database' => {
        'description' => 'Change database status',
        'script'      => 'do_update_reservations',
        'level'       => 1,
    },
    'reported' => {
        'description' => 'Report change to Matrix',
        'script'      => 'do_report',
        'level'       => 1,
    },
);
# }}}

_debug($DEBUG == 3, '%taghash: ' . Dumper(\%taghash));

#
# Enable Unicode mode
#
binmode STDOUT, ":encoding(UTF-8)";
binmode STDERR, ":encoding(UTF-8)";

#-------------------------------------------------------------------------------
# Argument 1 must be the episode number in '1234' or 'hpr1234' form
#-------------------------------------------------------------------------------
$showno = shift;
die "Usage: $PROG epno\n" unless $showno;
if (($showno) =~ /^(?:hpr)?(\d+)$/) {
    #
    # Make an id in 'hpr1234' format
    #
    $showid = sprintf('hpr%04d',$showno);
}
else {
    die "Invalid episode format: $showno\n";
}

#-------------------------------------------------------------------------------
# Set up logging keeping the default log layout except for the date. The format
# is "%T [%L] %m" where '%T' is the timestamp, '%L' is the log level and '%m is
# the message.
#-------------------------------------------------------------------------------
my $log = Log::Handler->new();

$log->add(
    file => {
        timeformat => "%Y/%m/%d %H:%M:%S",
        filename   => $logfile,
        minlevel   => 0,
        maxlevel   => 7,
    }
);

#
# Check the existence of the requested show directory
#
unless (-d "$cache/$showid") {
    die "Directory $cache/$showid not found\n";
}

$log->info("Processing show $showid");

#-------------------------------------------------------------------------------
# Collect show data
#-------------------------------------------------------------------------------
#
# Declared format
#
if ( -e "$cache/$showid/$formatfile" ) {
    chomp($showdata{format} = read_text("$cache/$showid/$formatfile"));
}
else {
    $showdata{format} = undef;
}

#
# Current status
#
if ( -e "$cache/$showid/$statusfile" ) {
    $showdata{statuslist} = [];
    push(@{$showdata{statuslist}}, read_lines("$cache/$showid/$statusfile"));
}
else {
    $showdata{statuslist} = undef;
}

#
# Assets
#
if ( -e "$cache/$showid/$assetfile" ) {
    $showdata{assets} = [];
    push(@{$showdata{assets}}, read_lines("$cache/$showid/$assetfile"));
    $taghash{assets}->{level} = 1;
}
else {
    $showdata{assets} = undef;
}

#
# Pictures (a subset of assets)
#
if ( -e "$cache/$showid/$picturefile" ) {
    $showdata{pictures} = [];
    push(@{$showdata{pictures}}, read_lines("$cache/$showid/$picturefile"));
    $taghash{pictures}->{level} = 1;
}
else {
    $showdata{pictures} = undef;
}

_debug($DEBUG == 3, '%showdata: ' . Dumper(\%showdata));

#-------------------------------------------------------------------------------
# Determine the incomplete steps in the workflow
#-------------------------------------------------------------------------------
$missed = 0;
for my $tag (@statustags) {
    my $th = $taghash{$tag};

    if ( $th->{level} == 1
        && scalar( grep( /$tag/, @{ $showdata{statuslist} } ) ) == 0 )
    {
        printf "%-40s (./%s %d)\n",
            "Missing '$th->{description}' step",
            $th->{script}, $showno;
        $missed++;
    }
}

#
# Nothing missed, so say so
#
say "Nothing to do for show $showno" if ($missed == 0);

exit;

#===  FUNCTION  ================================================================
#         NAME: _debug
#      PURPOSE: Prints debug reports
#   PARAMETERS: $active         Boolean: 1 for print, 0 for no print
#               $messages...    Arbitrary list of messages to print
#      RETURNS: Nothing
#  DESCRIPTION: Outputs messages if $active is true. It removes any trailing
#               newline from each one and then adds one in the 'print' to the
#               caller doesn't have to bother. Prepends each message with 'D>'
#               to show it's a debug message.
#       THROWS: No exceptions
#     COMMENTS: Differs from other functions of the same name
#     SEE ALSO: N/A
#===============================================================================
sub _debug {
    my $active = shift;

    my $message;
    return unless $active;

    while ($message = shift) {
        chomp($message);
        print STDERR "D> $message\n";
    }
}

# vim: syntax=perl:ts=8:sw=4:et:ai:tw=78:fo=tcrqn21:fdm=marker