#!/bin/env perl

# given a run id or exposure find the various inputs and run
# streaksremove
# Does not update the database or 'replace' the inputs

use strict;
use warnings;

use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
use Pod::Usage qw( pod2usage );
use File::Temp qw( tempfile );
use IPC::Cmd 0.36 qw( can_run run );
use PS::IPP::Metadata::Config;
use PS::IPP::Metadata::List qw( parse_md_list );
use PS::IPP::Config qw( :standard );
use File::Basename qw( basename dirname );


my ($exp_id, $chip_id, $cam_id, $warp_id, $diff_id, $stage, $component);
my ($outroot, $logfile, $dbname, $verbose, $save_temps);

GetOptions(
    'exp_id=s'      =>  \$exp_id,
    'chip_id=s'     =>  \$chip_id,
    'cam_id=s'      =>  \$cam_id,
    'warp_id=s'     =>  \$warp_id,
    'diff_id=s'     =>  \$diff_id,
    'stage=s'       =>  \$stage,
    'component=s'   =>  \$component,
    'outroot=s'     =>  \$outroot,
    'logfile=s'     =>  \$logfile,
    'dbname=s'      =>   \$dbname,
    'verbose'       =>  \$verbose,
    'save-temps'    =>  \$save_temps,

);

pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
pod2usage( -msg => "Required options: --chip_id | --cam_id | --warp_id | --diff_id --outroot",
           -exitval => 3) unless
    defined $outroot and
    ((defined $exp_id and defined $stage) or
     defined $chip_id or defined $cam_id or defined $warp_id or defined $diff_id);

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

my $camera = "GPC1";
my $destreak_command = "magic_destreak.pl --camera $camera --outroot  $outroot";
$destreak_command .= " --dbname $dbname" if $dbname;
$destreak_command .= " --verbose" if $verbose;
$destreak_command .= " --save-temps" if $save_temps;
$destreak_command .= " --logfile $logfile" if $logfile;

my $stmt;
my $query;
if ($chip_id) {
    $stage = "chip";

    $query =
"SELECT
    exp_id,
    chip_id,
    chipProcessedImfile.class_id,
    chipProcessedImfile.magicked,
    chipProcessedImfile.data_state,
    magicDSRun.magic_ds_id,
    magicMask.uri AS streaks_uri,
    chipProcessedImfile.path_base,
    magicDSFile.backup_path_base,
    camProcessedExp.path_base AS cam_path_base
    FROM chipRun
    JOIN chipProcessedImfile using(chip_id, exp_id)
    JOIN camRun using(chip_id)
    JOIN camProcessedExp using(cam_id)
    JOIN magicDSRun ON stage = 'chip' AND stage_id = chipRun.chip_id
--  AND camRun.cam_id = magicDSRun.cam_id
    JOIN magicDSFile ON magicDSRun.magic_ds_id = magicDSFile.magic_ds_id
    AND class_id = component
    JOIN magicRun using(magic_id, exp_id)
    JOIN magicMask using(magic_id)
    WHERE chipProcessedImfile.quality = 0
        AND chipProcessedImfile.data_state = 'full'
        AND chip_id = $chip_id";

    $query .= " AND class_id = '$component'" if $component;
    $stmt = $dbh->prepare($query);
    $stmt->execute();

    $destreak_command .= " --stage chip ";
    my $processed = 0;
    while (my $imfile = $stmt->fetchrow_hashref()) {
        $processed++;
        my $class_id = $imfile->{class_id};
        my $path_base = $imfile->{path_base};
        my $magicked = $imfile->{magicked};
        my $streaks = $imfile->{streaks_uri};
        my $cam_path_base = $imfile->{cam_path_base};
        my $uri;
        if ($magicked > 0) {
            # get source of image from "backup"
#            my $dirname = dirname($path_base);
#            my $base = basename($path_base);
#            $path_base = $dirname . "/SR_" . $base;
            $path_base = $imfile->{backup_path_base};
        }
        $uri = "$path_base.$class_id.ch.fits";
        my $command = "$destreak_command --magic_ds_id $imfile->{magic_ds_id}"
            . " --exp_id $imfile->{exp_id}"
            . " --stage_id $chip_id"
            . " --component $imfile->{class_id}"
            . " --cam_path_base $cam_path_base"
            . " --streaks $streaks"
            . " --path_base $path_base"
            . " --uri $uri"
            . " --no-update"
            . " --magicked 0"

            ;

        print "$command\n";
        system $command;
    }
    if (!$processed) {
        print STDERR "no images destreaked for $chip_id\n";
        exit 1;
    }
} elsif ($warp_id) {
    $stage = "warp";

    $query =

"SELECT
    exp_id,
    warp_id,
    warpSkyfile.skycell_id,
    warpSkyfile.magicked,
    warpSkyfile.data_state,
    magicDSRun.magic_ds_id,
    magicMask.uri AS streaks_uri,
    warpSkyfile.path_base,
    magicDSFile.backup_path_base
    FROM warpRun
    JOIN warpSkyfile using(warp_id)
    JOIN magicDSRun ON stage = 'warp' AND stage_id = warpRun.warp_id
    JOIN magicDSFile ON magicDSRun.magic_ds_id = magicDSFile.magic_ds_id
                        AND skycell_id = component
    JOIN magicRun using(magic_id)
    JOIN magicMask using(magic_id)
    WHERE warpSkyfile.quality = 0
        AND warpSkyfile.data_state = 'full'
        AND warp_id = $warp_id";

    $query .= " AND skycell_id = '$component'" if $component;

    print "$query\n" if $verbose;

    $stmt = $dbh->prepare($query);
    $stmt->execute();

    $destreak_command .= " --stage warp ";
    my $num_rows = 0;
    while (my $imfile = $stmt->fetchrow_hashref()) {
        $num_rows++;
        my $skycell_id = $imfile->{skycell_id};
        my $path_base = $imfile->{path_base};
        my $magicked = $imfile->{magicked};
        my $streaks = $imfile->{streaks_uri};
        my $uri;
        if ($magicked > 0) {
            # get source of image from "backup"
#            my $dirname = dirname($path_base);
#            my $base = basename($path_base);
#            $path_base = $dirname . "/SR_" . $base;
            $path_base = $imfile->{backup_path_base};
        }
        $uri = "$path_base.fits";
        my $command = "$destreak_command --magic_ds_id $imfile->{magic_ds_id}"
            . " --exp_id $imfile->{exp_id}"
            . " --stage_id $warp_id"
            . " --component $skycell_id"
            . " --streaks $streaks"
            . " --path_base $path_base"
            . " --uri $uri"
            . " --no-update"
            . " --magicked 0"
        ;

        print "$command\n";
        system $command;
    }
    if (!$num_rows) {
        print STDERR "query returned no rows for warp_id: $warp_id\n";
        exit 1;
    }
} else {
    die "only implemented for chip and warp as yet";
}

exit 0;

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;
}

