#!/usr/bin/env perl

# This program runs on the local server to invoke KNOWN_SERVER on
# a designated host.  The remote KNOWN process is invoked vi
# ssh using KNOWN_REMOTE.


=head1 NAME

KNOWN_LOCAL - Local processing for KNOWN_SERVER

=head1 SYNOPSIS

KNOWN_LOCAL [options] --nn NIGHT_NUMBER

  --nn NIGHT_NUMBER : night number to process
  --field_status=X : only use tracklets from fields with specified status
  --all_nights : process all nights (instead of --nn NIGHT_NUMBER)
  --mark_status STATUS : mark tracklets with specified tracklet status
  --instance=INSTANE_NAME : specify simulation to use

=head1 DESCRIPTION

Sets up export for KNOWN_SERVER processing, then invokes KNOWN_REMOTE
on the remote server.  After completion, looks for .out.orbit files and
ingests KNOWN decorations against the current MOPS instance.

=cut

use warnings;
use strict;

use Getopt::Long;
use Pod::Usage;
use FileHandle;
use File::Path;
use Cwd;

use PS::MOPS::DC::Instance;
use PS::MOPS::Lib qw(:all);
use PS::MOPS::Constants qw(:all);

my $instance_name;
my $inst;
my $nn;
my $field_status;
my $all_nights;
my $mark_status;
my $export_only;
my $help;

GetOptions(
    'instance=s' => \$instance_name,
    'nn=i' => \$nn,
    'field_status=s' => \$field_status,
    all => \$all_nights,
    'mark_status=s' => \$mark_status,
    export_only => \$export_only,
    help => \$help,
) or pod2usage(2);                      # opts parse error
pod2usage(-verbose => 3) if $help;      # user asked for help
pod2usage(-msg => '--nn NIGHT_NUMBER or --all_nights is required') unless ($nn or $all_nights);

$inst = PS::MOPS::DC::Instance->new(DBNAME => $instance_name);
my $dbname = $inst->dbname();
my $mops_config = $inst->getConfig();
my $mops_logger = $inst->getLogger();

if ($all_nights) {
    $nn = 'all';
}


# Set up our dirs from config.
my $known_host = $mops_config->{known}->{host};
my $local_export_dir = $mops_config->{known}->{local_export_dir};
my $local_data_dir = "$local_export_dir/$dbname.$nn";

my $remote_export_dir = $mops_config->{known}->{remote_export_dir};
my $remote_data_dir = "$remote_export_dir/$dbname.$nn";

my $status_str = '';
if ($mark_status) {
    $status_str = "--status=$mark_status";
}

my $cwd = getcwd();
eval {
    $mops_logger->info("KNOWN_LOCAL: starting");

    # Clean up any previous run.
    chdir $local_export_dir or die "can't chdir to $local_export_dir";
    if (-e $local_data_dir) {
        eval { rmtree("$local_data_dir") };
        die "can't remove data dir $local_data_dir: $@" if $@;
    }

    # Make directories.
    chdir $local_export_dir or die "can't chdir to $local_export_dir";
    eval { mkpath("$local_data_dir") };
    die "can't create data dir $local_data_dir: $@" if $@;

    # Export our data.
    chdir $local_data_dir or die "can't chdir $local_data_dir";
    if ($all_nights) {
        system("export_known --name MOPS") == 0 or die $?;
    }
    else {
        my $field_status_str = $field_status ? "--field_status=$field_status" : '';
        system("export_known $field_status_str --nn=$nn --name MOPS") == 0 or die $?;
    }

    if ($export_only) {
        print "ssh $known_host 'KNOWN_REMOTE $remote_data_dir'\n";
        exit(0);
    }

    # Run the remote processing.
    system("ssh $known_host 'KNOWN_REMOTE $remote_data_dir'") == 0 or die $?;

    # Ingest the results.
    my ($ident, $orb);
    ($ident, $orb) = (
        "$local_data_dir/run/MOPSn/ID1/MOPSn_nor.out.ident_header",
        "$local_data_dir/run/MOPSn/ID1/MOPSn_nor.out.orbit",
    );
    if (-f $ident and -f $orb) {
        system("decorateKnown $status_str $ident $orb") == 0 or die $?;
    }
    else {
        $mops_logger->logwarn("KNOWN_LOCAL: missing $ident or $orb; skipping");
    }

    ($ident, $orb) = (
        "$local_data_dir/run/MOPSm/ID1/MOPSm_nor.out.ident_header",
        "$local_data_dir/run/MOPSm/ID1/MOPSm_nor.out.orbit",
    );
    if (-f $ident and -f $orb) {
        system("decorateKnown $status_str $ident $orb") == 0 or die $?;
    }
    else {
        $mops_logger->logwarn("KNOWN_LOCAL: missing $ident or $orb; skipping");
    }
};

$mops_logger->logdie($@) if $@;
exit;

