#!/usr/bin/env perl
#===============================================================================
#
#        USAGE: ./rfc  --help --testing update|create {id}|recreate|clean
#
#  DESCRIPTION: utility wrapper round LIMS::Local::RfC
#===============================================================================

use Modern::Perl;
use utf8;
use Getopt::Long;
use Try::Tiny;
use FindBin qw($RealBin);
use lib "$RealBin/../lib";
use lib $RealBin . '/prereq_lib'; # make sure we are using old HTTP::Tiny
use HTTP::Tiny;
# check we are using use old HTTP::Tiny in prereq_lib
# because SSLeay isnt uptodate on hilis server
die unless $HTTP::Tiny::VERSION eq '0.012';
use LIMS::Local::Config;
use LIMS::Local::ScriptHelpers;
use LIMS::Local::RfC;



my $config = LIMS::Local::Config->instance;
my $tools  = LIMS::Local::ScriptHelpers->new;

#defaults to production regardless of config so modify in testing mode
my $dbix = $tools->dbix;

# setup my defaults
my $help    = 0;
my $testing = 0;

GetOptions(
    'testing!' => \&testing,
    'help!' => \$help,
) or die "Incorrect usage!\n";

my $rfc;
$rfc = LIMS::Local::RfC->new( { database => $dbix } );

my %dispatch = (
    update   => \&update,
    create   => \&create,
    recreate => \&recreate,
    clean    => \&clean,
);

usage() unless @ARGV;

my $function  = shift @ARGV;
    unless ( exists $dispatch{ $function } ) {
        warn "unknown command: $function";
        usage();
    }

$dispatch{$function}->(@ARGV);

sub testing {
    $testing = 1;
    #$ENV{HARNESS_ACTIVE} = 1;    # force issuetracker to use test board
    $ENV{TESTRUN} =1;
    warn "testing: using test board";
    $dbix->dbh->do('USE lims_test'); # assuming it exists
    #$dbix->dbh->do( 'use ' . $config->{settings}->{development_db} );
}

# update status for any incomplete rfcs in database
# check 'complete' and 'rejected' boards
sub update {
    # say "updating statuses";# RJ 10/2/18 - polluting cron.log
    my @incomplete = $rfc->find_incomplete_rfcs();
    $rfc->update_rfcs(@incomplete);
}

# tidy up test board
sub clean {
    if ($testing) {
        $rfc->tracker->archive_issues($_) for qw/new complete rejected/;
    }
    else { die "clean must be used with --testing option"; }
}

# creates issues in tracker that didnt get created when rfc was submitted
sub create {
    my $id = shift;
    if ($id) {
        # say "creating issue from DB id"; # RJ 10/2/18 - polluting cron.log
        my $record = $rfc->get_rfc($id);
        $rfc->recreate_issue($record);
    }
    else {
        # say "creating issues from orphans in DB"; # RJ 10/2/18 - polluting cron.log
        my @orphans = $rfc->find_orphans;
        $rfc->recreate_issue($_) for @orphans;
    }
}
# find incomplete rfcs (with remote_ids) and check their status. If they
# dont exist, recreate them.
sub recreate {
    my $id = shift;
    if ($id) {
        # say "recreating lost issue from DB id"; # RJ 10/2/18 - polluting cron.log
        my $record = $rfc->get_rfc($id);
        $rfc->recreate_issue($record);
    }
    else {
        # say "recreating lost rfcs"; # RJ 10/2/18 - polluting cron.log
        my @lost = $rfc->find_incomplete_rfcs();
        $rfc->recreate_issue($_) for @lost;
    }
}

sub usage {
    my $message = $_[0] // '';
    if ( defined $message && length $message ) {
        $message .= "\n"
          unless $message =~ /\n$/;
    }

    my $command = $0;
    $command =~ s#^.*/##;

    print STDERR (
        $message,
        "USAGE: $command [--testing] create|recreate|update|clean\n"
          . "OR: $command [--testing] create {id}\n\n"
          . "--testing: use test issuetracker board"
          . "create:    adds cards that are in database but have no remote_id\n"
          . "recreate:  adds or unarchives cards that are in database\n"
          . "update:    sets status of records in database if complete or rejected\n"
          . "clean:     deletes records from test tracker"
          . "--help:    this help"
    );

    die("\n");
}
