#!/usr/bin/env perl

use warnings;
use strict;

use DBI;

use IPC::Cmd 0.36 qw( can_run run );
use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
use Pod::Usage qw( pod2usage );
use Data::Dumper;
use File::Temp qw( tempfile );

use PS::IPP::Metadata::Config;
use PS::IPP::Metadata::List qw( parse_md_list );
use PS::IPP::Config qw( caturi );

# Look for programs we need
my $missing_tools;
my $mops = can_run('ipp_mops_translate.pl') or (warn "Can't find ipp_mops_translate.pl" and $missing_tools = 1);
my $dsreg = can_run('dsreg') or (warn "Can't find dsreg" and $missing_tools = 1);
die "Can't find required tools.\n" if $missing_tools;

my $ipprc = PS::IPP::Config->new; # IPP Configuration

my ( $dbhost,                   # Database host
     $dbname,                   # Database name
     $dbuser,                   # Database user
     $dbpass,                   # Database p/w
     $camera,                   # Camera used
     $outroot,                  # Output directory
     $fileset,                  # File set
     $label,                    # Data label to search for
     $verbose,                  # Verbose output?
     $no_update,                # Don't update state?
     $no_op,                    # Don't do any operations?
     $save_temps                # Save temporary files?
     );

GetOptions(
           'dbhost=s'   => \$dbhost,
           'dbname=s'   => \$dbname,
           'dbuser=s'   => \$dbuser,
           'dbpass=s'   => \$dbpass,
           'camera=s'   => \$camera,
           'outroot=s'  => \$outroot,
           'fileset=s'  => \$fileset,
           'label=s'    => \$label,
           'verbose'    => \$verbose,
           'no-update'  => \$no_update, # Don't update the database?
           'no-op'      => \$no_op, # Don't do any operations?
           'save-temps' => \$save_temps, # Save temporary files?
) or pod2usage( 2 );

pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
pod2usage( -msg => "Required options: --dbhost --dbname --dbuser --dbpass --camera --outroot --fileset",
           -exitval => 3)
    unless defined $dbhost
    and defined $dbname
    and defined $dbuser
    and defined $dbpass
    and defined $camera
    and defined $outroot
    and defined $fileset;

$ipprc->define_camera($camera);

my $dbsrc = 'DBI:mysql:database=' . $dbname . ';host=' . $dbhost .
    ';mysql_socket=/var/run/mysqld/mysqld.sock';
my $db = DBI->connect($dbsrc, $dbuser, $dbpass, { RaiseError => 1, AutoCommit => 1 } ) or
    die "Unable to connect to database: $DBI::errstr";

my $sql = "SELECT exp_id, diff_id, skycell_id, warp_id, diffSkyfile.path_base AS diff_path_base, warpSkyfile.path_base AS warp_path_base FROM diffSkyfile JOIN diffRun using(diff_id) JOIN diffInputSkyfile USING(diff_id,tess_id,skycell_id) JOIN warpRun USING(warp_id,tess_id) JOIN warpSkyfile USING(warp_id,skycell_id,tess_id) JOIN fakeRun using(fake_id) JOIN camRun USING(cam_id) JOIN chipRun USING(chip_id) JOIN rawExp USING(exp_id) WHERE diffSkyfile.fault = 0 AND rawExp.camera = \'$camera\'";
$sql .= " AND diffRun.label = \'$label\'" if defined $label;
$sql .= ';';

my $rows = $db->selectall_arrayref( $sql, { Slice => {} } ) or die "Unable to execute SQL: $DBI::errstr";
$db->disconnect;

print "Selected " . scalar @$rows . " rows.\n";

$ipprc->outroot_prepare( $outroot );
my $outrootResolved = $ipprc->file_resolve( $outroot );
my ($dsFile, $dsName) = tempfile( "$outrootResolved.dslist.XXXX", UNLINK => !$save_temps);

foreach my $row ( @$rows ) {
    my $exp_id = $row->{exp_id};
    my $diff_id = $row->{diff_id};
    my $skycell_id = $row->{skycell_id};
    my $warp_id = $row->{warp_id};
    my $diff_base = $row->{diff_path_base};
    my $warp_base = $row->{warp_path_base};

    my $input = $ipprc->filename("PSPHOT.OUT.CMF.MEF", $diff_base);
    die "Can't find $input\n" unless $ipprc->file_exists($input);
    $input = $ipprc->file_resolve($input);

    my $skycell = $ipprc->filename("SKYCELL.TEMPLATE", $warp_base);
    die "Can't find $skycell\n" unless $ipprc->file_exists($skycell);
    $skycell = $ipprc->file_resolve($skycell);

    my $output = caturi( $outroot, "mops.$exp_id.$skycell_id.$diff_id.fits" );
    $output = $ipprc->file_resolve($output);

    unless ($no_op) {
        $ipprc->file_prepare($output);
        my $command = "$mops --input $input --extname SkyChip.psf --skycell $skycell --output $output";
        my $success = run( command => $command, verbose => $verbose );
        die "Couldn't translate $input\n" unless $success;
    }

    # format: filename|filesize|md5sum|filetype|
    # note: since we omit filesize and md5sum, dsreg will calculate them
    print $dsFile "${output}|||ipp-mops|\n";
}
close $dsFile;

# Register new files with the data store
unless ($no_update) {
    my $command = "$dsreg --add $fileset --product mops_transient_detections --type MOPS_TRANSIENT_DETECTIONS --list $dsName --copy --abspath --dbname DataStore";
    my $success = run( command => $command, verbose => $verbose );
    die "Couldn't register files with data store.\n" unless $success;
}


__END__

