#!/usr/bin/env perl

# Given an ra, dec (or CAT_ID), exp_id, class_id, and det_id (IPP_IDET) for a detection,
# lookup the detection it in the corresponding dvo measures file.
# output is text unless an output file is specified.
# With the option --list-others to output all measures for the given detection's object.
# if --det_id is omitted, the catalog name and IMAGE_ID for the corresponding exposure is
# printed to stdout

use strict;
use warnings;

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

my ($ra, $dec, $cat_id, $exp_id, $class_id, $stack_id, $det_id);

my ($outputFile, $ofmt, $save_temps, $verbose);

my ($listOthers, $thisImage);
GetOptions(
    "ra=s"              =>  \$ra,
    "dec=s"             =>  \$dec,
    "cat_id=s"          =>  \$cat_id,
    "exp_id=s"          =>  \$exp_id,
    "class_id=s"        =>  \$class_id,
    "stack_id=s"        =>  \$stack_id,
    "det_id=s"          =>  \$det_id,
    "list-others"       =>  \$listOthers,
    "this-image"        =>  \$thisImage,
    "output|o=s"        =>  \$outputFile,
    "ofmt=s"            =>  \$ofmt,

    "verbose|v"         =>  \$verbose,
    "save-temps"        =>  \$save_temps,
) or pod2usage( 2 );

unless (defined $ra and defined $dec and (defined $stack_id or (defined $exp_id and defined $class_id)) ) {
    print STDERR "usage: $0 --ra <ra> --dec <dec> [--cat_id <cat_id>] (--exp_id <exp_id> --class_id <class_id> | --stack_id <stack_id>) [--det_id <det_id>] [--output <output file name>]\n";
    print STDERR "       Other options: --list-others --this-image --ofmt\n";
    exit 1;
}


my $dvo = can_run('dvo') or die "Can't find dvo";
my $java = can_run('java') or die "Can't find java";
my $chiptool = can_run('chiptool') or die "Can't find chiptool";

my $stilts = "$java -jar $ENV{HOME}/ipp/ippToPsps/jars/stilts.jar";

# XXX: make label and catdir options
# XXX: should be using release_name which will have pointers to the right datat and the catdir
my $label = "SAS.20141118";
my $catdir = '/data/ipp079.0/gpc1/catdirs/SAS/SAS39.V1';

# go find which catalog this detection should belong to
# in the SkyTable
my $catalog;
if ($cat_id) {
    # We have CAT_ID select using that
    my $command = "$stilts tpipe ofmt=ascii cmd='addcol CAT_ID INDEX;select CAT_ID==$cat_id;keepcols NAME;'"
        . " in=$catdir/SkyTable.fits";

    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
        run(command => $command, verbose => $verbose);
    unless ($success) {
        print STDERR "command failed error code: $error_code\nstderr says:\n\t";
        print STDERR @$stderr_buf;

        my $exit_status = $error_code >> 8;
        print STDERR "exiting with status $exit_status\n";
        exit $exit_status;
    }
    my $output = join "", @$stdout_buf;
    my @lines = split "\n", $output;
    # result is on the second line. split is an easy way to strip off whitespace
    ($catalog) = split " ", $lines[1];
} else {
    # WE only have RA and DEC find the catalog using dvo's gcat command
    # Note: leaving off the quit in the command causes dvo to exit with an error. Probably because the pipe
    # unexpectedly went away.
    my $command = "echo 'gcat $ra $dec;quit' | dvo -D CATDIR $catdir";
    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
        run(command => $command, verbose => $verbose);
    unless ($success) {
        print STDERR "command failed error code: $error_code\nstderr says:\n\t";
        print STDERR @$stderr_buf;

        my $exit_status = $error_code >> 8;
        print STDERR "exiting with status $exit_status\n";
        exit $exit_status;
    }
    # gcat results go to stderr
    my $output = join "", @$stderr_buf;
    my @lines = split "\n", $output;
    my $nlines = scalar @lines;
    my $lastline = $lines[$nlines-1];
    # printf "%s\n", $lastline;
    (undef, $catalog, undef) = split " ", $lastline;

    # XXX: we could go and the find $cat_id if we need it here.
    $cat_id = 'NULL';
}

my $catalogPrefix = "$catdir/$catalog";
# print "$catalogPrefix\n";

# Go and find the EXTERN_ID (chip_imfile_id) for this image
my $extern_id;
my $image_id;
if ($exp_id) {
    my $command = "$chiptool -processedimfile -exp_id $exp_id -class_id $class_id -label $label | grep chip_imfile_id | awk '{print \$3}'";
    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
        run(command => $command, verbose => $verbose);
    unless ($success) {
        print STDERR "command failed error code: $error_code\nstderr says:\n\t";
        print STDERR join "", @$stderr_buf;

        my $exit_status = $error_code >> 8;
        print STDERR "exiting with status $exit_status\n";
        exit $exit_status;
    }
    my $output = join "", @$stdout_buf;
    chomp $output;
    $extern_id = $output;
} else {
    die "Need exp_id or stack_id!!\n" unless $stack_id;
    $extern_id = $stack_id;
}

# go and find the IMAGE_ID for this image in the Images.dat
{
    my $command = "$stilts tpipe in=$catdir/Images.dat cmd='select EXTERN_ID==$extern_id;keepcols IMAGE_ID;' ofmt=ascii";

    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
        run(command => $command, verbose => $verbose);
    unless ($success) {
        print STDERR "command failed error code: $error_code\nstderr says:\n\t";
        print STDERR @$stderr_buf;

        my $exit_status = $error_code >> 8;
        print STDERR "exiting with status $exit_status\n";
        exit $exit_status;
    }
    my $output = join "", @$stdout_buf;
    my @lines = split "\n", $output;
    # result is on the second line. split is an easy way to remove whitespace
    ($image_id) = split " ", $lines[1];
}

# Print out what we've found out so far
print "RA            DEC      NAME     CAT_ID EXTERN_ID IMAGE_ID catalogPrefix\n";
#      333.71999 -4.47253 s0000/5228.01 NULL 75160686 4620 /data/ipp079.0/gpc1/catdirs/SAS/SAS39.V1/s0000/5228.01
print "$ra $dec $catalog $cat_id $extern_id $image_id $catalogPrefix\n";

if (!$det_id) {
    exit 0;
}

# We have a det_id go find the detection(s) in the catalog
{
    my $command = "$stilts tpipe in=$catalogPrefix.cpm cmd='select IMAGE_ID==$image_id&&DET_ID==$det_id;";
    if ($listOthers) {
        # just get the OBJ_ID
        $command .= "keepcols OBJ_ID;' ofmt=ascii";
    } else {
        # We only need the specific detection
        $command .= "'";
        $command .= " out=$outputFile" if $outputFile;
        $command .= " ofmt=$ofmt" if $ofmt;
    }

    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
        run(command => $command, verbose => $verbose);
    unless ($success) {
        print STDERR "command failed error code: $error_code\nstderr says:\n\t";
        print STDERR @$stderr_buf;

        my $exit_status = $error_code >> 8;
        print STDERR "exiting with status $exit_status\n";
        exit $exit_status;
    }
    my $output = join "", @$stdout_buf;

    if ($listOthers) {
        # find the obj_id for our detection
        my @lines = split "\n", $output;
        # result is on the second line. split is an easy way to remove whitespace
        my ($obj_id) = split " ", $lines[1];
        my $extraSelect = "";
        if ($thisImage) {
            # just list detections from this object in this image
            $extraSelect = "&&IMAGE_ID==$image_id";
        }
            
        my $command = "$stilts tpipe in=$catalogPrefix.cpm cmd='select OBJ_ID==$obj_id$extraSelect;";
        $command .= "'";
        $command .= " out=$outputFile" if $outputFile;
        $command .= " ofmt=$ofmt" if $ofmt;
        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
            run(command => $command, verbose => $verbose);
        unless ($success) {
            print STDERR "command failed error code: $error_code\nstderr says:\n\t";
            print STDERR @$stderr_buf;

            my $exit_status = $error_code >> 8;
            print STDERR "exiting with status $exit_status\n";
            exit $exit_status;
        }
        $output = join "", @$stdout_buf;
    }
    if (!$outputFile) {
        # user did not specify an output file list the results of the commands above
        print $output;
    }
}

exit 0;



# find the chip_imfile_id of the exposure and ota
# $extern_id = `chiptool -processedimfile -exp_id $exp_id -class_id $class_id -label SAS.20141118 | grep chip_imfile_id | awk '{print $3}'`

# look up the IMAGE_ID in the Images.Dat

#stilts tpipe in=../Images.dat cmd='select "EXTERN_ID==$extern_id";keepcols IMAGE_ID"'

# Look up the catalog name for the coordinates using dvo's gcat command

