#!/usr/bin/env perl
#
# Execute a get_image job for the postage stamp server
#

use strict;
use warnings;

use Getopt::Long qw( GetOptions );
use Pod::Usage qw( pod2usage );
use DBI;
use PS::IPP::Metadata::Config;
use PS::IPP::Metadata::Stats;
use PS::IPP::Metadata::List qw( parse_md_list );
use File::Copy;
use File::Basename;
use Digest::MD5::File qw( file_md5_hex );
use IPC::Cmd 0.36 qw( can_run run );


use PS::IPP::Config qw( :standard );

my $product;
my $fileset;

my $output_base;

my $verbose;
my $ipprc;
my $dbname;
my $dbserver;
my $job_id;
my $rownum;

#
# parse args
#

GetOptions(
        'job_id=s'        =>      \$job_id,
        'rownum=s'        =>      \$rownum,
        'output_base=s'   =>      \$output_base,
        'dbname=s'        =>      \$dbname,
        'dbserver=s'      =>      \$dbserver,
        'verbose'         =>      \$verbose,
) or pod2usage(2);

my $err = "";
$err .= "--job_id is required\n" if (!$job_id);
$err .= "--rownum is required\n" if (!$rownum);
$err .= "--output_base is required to specify the output fileset\n" if (!$output_base);

my_die( $err, $PS_EXIT_PROG_ERROR) if $err;

my $params_file = $output_base . ".mdc";
if (! open(INPUT, "<$params_file") ) {
    my_die("failed to open params file: $params_file", $PS_EXIT_UNKNOWN_ERROR);
}

my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files

my $data = $mdcParser->parse(join "", (<INPUT>)) or my_die("failed to parse metadata config doc", $PS_EXIT_UNKNOWN_ERROR);
my $components = parse_md_list($data);
my $n = scalar @$components;
if ($n != 1) {
    my_die("params file $params_file contains unexpected number of components: $n", $PS_EXIT_PROG_ERROR);
}
my $comp = $components->[0];
my $stage = $comp->{stage};
my $stage_id = $comp->{stage_id};
my $component = $comp->{component};
my $path_base = $comp->{path_base};
my $camera = $comp->{camera};
my $magicked = $comp->{magicked};

if ($verbose) {
    print STDERR "\nstage is $stage\n";
    print STDERR "stage_id is $stage_id\n";
    print STDERR "path_base is $path_base\n";
    print STDERR "path_base is $path_base\n";
    print STDERR "CAMERA is $camera\n";
    print STDERR "magicked is " . (defined $magicked ? $magicked : "undefined") . "\n";
}

if (!$camera or !$path_base or !$component or !$stage_id or !$stage) {
       my_die("failed to parse params from: $params_file", $PS_EXIT_UNKNOWN_ERROR);
}

my $out_dir = dirname($output_base);
my $prefix = basename($output_base) . "_";
my $results_file = $output_base . ".bundle_results";

# Look for programs we need
my $missing_tools;
my $dist_bundle   = can_run('dist_bundle.pl') or (warn "Can't find dist_bundle.pl" and $missing_tools = 1);
if ($missing_tools) {
    warn("Can't find required tools.");
    exit($PS_EXIT_CONFIG_ERROR);
}

{
    my $command = "$dist_bundle --camera $camera --stage $stage --stage_id $stage_id";
    $command .= " --component $component";
    $command .= " --path_base $path_base --outdir $out_dir --results_file $results_file";
    $command .= " --prefix $prefix";
    $command .= " --magicked" if $magicked;
    $command .= " --dbname $dbname" if $dbname;
    $command .= " --verbose" if $verbose;
    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
        run(command => $command, verbose => $verbose);
    unless ($success) {
        my_die("Unable to perform $command: $error_code", $error_code >> 8);
    }
}

if (! open(RESULTS, "<$results_file")) {
    my_die("failed to open bundle results file: $results_file", $PS_EXIT_UNKNOWN_ERROR);
}

my $file_name;
my $bytes;
my $md5sum;
foreach my $line (<RESULTS>) {
    chomp $line;
    next if !$line;
    next if $line =~ /bundleResults/;
    last if $line =~ /END/;

    my ($tag, $type, $val) = split " ", $line;
    if ($tag eq "name") {
        $file_name = $val;
    } elsif ($tag eq "bytes") {
        $bytes = $val;
    } elsif ($tag eq "md5sum") {
        $md5sum = $val;
    } else {
        my_die("unexpected tag: $tag  found in results file: $results_file", $PS_EXIT_PROG_ERROR);
    }
}

my $reglist = "$out_dir/reglist$job_id";
if (! open(REGLIST, ">$reglist") ) {
    my_die("failed to open registration list: $reglist", $PS_EXIT_UNKNOWN_ERROR);
}

print REGLIST "$file_name|$bytes|$md5sum|tgz|\n";

close(REGLIST);

exit 0;

sub my_die {
    my $msg = shift;
    my $rc = shift;

    print STDERR $msg;
    exit $rc ? $rc : $PS_EXIT_UNKNOWN_ERROR;
}
