#!/bin/env perl

use strict;
use warnings;
use DBI;
use IPC::Cmd 0.36 qw( can_run run );
use PS::IPP::Metadata::Config;
use PS::IPP::Config 1.01 qw( :standard );

use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
use Pod::Usage qw( pod2usage );
use File::Basename;
use IO::File;

my ($first, $last, $stage, $alt_workdir, $no_verbose);

my $dbname = "gpc1";
my ($chip_bg_id, $class_id, $threads, $update, $redirect, $pretend, $save_temps);

my $zaplog;

GetOptions(
    'chip_bg_id=i'         => \$chip_bg_id,
    'class_id=s'      => \$class_id,
    'threads=i'         => \$threads,
    'pretend'           => \$pretend,
    'zaplog'            => \$zaplog,
    'redirect-output'   => \$redirect,
    'update'            => \$update,
    'dbname=s'          => \$dbname,
    'no-verbose'        => \$no_verbose, 
    'save-temps'        => \$save_temps,
) or pod2usage( 2 );

pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
pod2usage( -msg => "--chip_bg_id and --class_id are required", -exitval => 2 )
    if !$chip_bg_id or !$class_id;

my $ipprc =  PS::IPP::Config->new();
my $dbh = getDBHandle();

my $query1 = "SELECT chipBackgroundImfile.path_base, camera, exp_id, chipBackgroundImfile.fault, chipBackgroundRun.reduction, chipBackgroundRun.state";
$query1 .= " FROM chipBackgroundRun join chipBackgroundImfile using(chip_bg_id) JOIN chipRun using(chip_id) JOIN rawExp using(exp_id) WHERE chip_bg_id = $chip_bg_id AND class_id = '$class_id'";

my $stmt1 = $dbh->prepare($query1);
$stmt1->execute();
my $results = $stmt1->fetchrow_hashref();
die "query returned no results\n" if !$results;
my $path_base = $results->{path_base};
my $reduction = $results->{reduction};
my $camera = $results->{camera};
my $state = $results->{state};
my $fault = $results->{fault};
my $deburned = $results->{deburned};
my $exp_id = $results->{exp_id};

die "cannot update database for a chip that is not faulted\n" if $update and !$fault;

die "path_base not found\n" if !$path_base;
die "camera not found\n" if !$camera;
die "state not found\n" if !$state;

my  $run_state;
if ($state eq 'full' or $state eq 'new') {
    $run_state = 'new';
} elsif ($state eq 'update') {
    $run_state = 'update';
} else {
    die "unexpected chipRun.state found: $state\n";
}

my $command = "background_chip.pl --chip_bg_id $chip_bg_id --class_id $class_id --camera $camera --outroot $path_base" ;

$command .= " --reduction $reduction" if $reduction and ($reduction ne "NULL");
$command .= " --redirect-output" if $redirect;
$command .= " --save-temps" if $save_temps;
$command .= " --no-update" unless $update;
$command .= " --verbose" unless $no_verbose;
$command .= " --dbname $dbname" if $dbname;

if ($update) {
    my $revert_command = "bgtool -revertchip -chip_bg_id $chip_bg_id -class_id $class_id -dbname $dbname";
    if ($pretend) {
        print "skipping $revert_command\n";
    } else {
        my $rc = system $revert_command;
        if ($rc != 0) {
            my $status = $rc >> 8;
            print STDERR "$revert_command failed: $rc $status\n";
            exit $status;
        }
    }
}
print "command to process this chip\n";
print "$command\n";

exit 0 if $pretend;

my $rc = system $command;
my $status = $rc >> 8;
if ($rc) {
    print "command returned $rc $status\n";
}
exit $status;


sub getDBHandle {
    my $dbserver = metadataLookupStr($ipprc->{_siteConfig}, "DBSERVER");
    my $dbuser = metadataLookupStr($ipprc->{_siteConfig}, "DBUSER");
    my $dbpassword = metadataLookupStr($ipprc->{_siteConfig}, "DBPASSWORD");
    if (!$dbname) {
        $dbname = metadataLookupStr($ipprc->{_siteConfig}, "DBNAME");
    }

    die "database configuration set up" unless defined($dbserver) and defined($dbuser)
        and defined($dbpassword) and defined($dbname);

    my $dsn = "DBI:mysql:host=$dbserver;database=$dbname";

    my $dbh = DBI->connect($dsn, $dbuser, $dbpassword) 
        or die "Cannot connect to database.\n";

    return $dbh;
}

__END__

=pod

=head1 NAME

runchipimfile.pl - gather the parameters for and execute chip_imfile.pl

=head1 SYNOPSIS
    
    XXX: pod TODO

    perl runwarpskyfile.pl --warp_id <warp_id> --skycell_id <skycell_id> [--threads <num_threads>] [--update] [--redirect-output] [--pretend] [--dbname <dbname>]

Query the database for the results of a warp skycell and rerun the processing, optionally reverting a faulted
run.

=over 4

=item * --warp_id <warp_id>

The id of the warpSkyfile run to process.

=item * --skycell_id <skycell_id>

The skycell_id of the warpSkyfile run to process.

=item * --threads <num_threads>

The number of threads to use. Default 1.
Optional.


=item * --update

Revert a faulted skycell before processing. If the skycell is not faulted no processing is done.
WARNING: insure that the standard science procesing either has warp stage turned off or the
label of this warpRun ommited from the list of labels otherwise it may attempt to processes this run at the same time.
Optional.

=item *  --redirect-output

Send the output of the command to the logfile. (This is the default if --update is supplied).
Optional.

=item * --pretend

Just print the commands that would be executed, but do not run them.
Optional.

=item * --dbname <dbname>

Name of the IPP databse to query. Default is 'gpc1'.
Optional.


=head1 SEE ALSO
L<runchipimfile.pl>, L<runcameraexp.pl>, L<rundiffskyfile.pl>

=cut
