#!/usr/bin/env perl

use strict;
use warnings;

use FileHandle;
use File::Slurp;
use Getopt::Long;
use Pod::Usage;

use PS::MOPS::Log;
use PS::MOPS::MITI;


my $help;
my $tracksfile;         # file containing MITI tracks
my $cleanfilt;          # filter tracks using this prefix
my $showunfound;
GetOptions(
    'tracks=s' => \$tracksfile,
    'cleanfilt=s' => \$cleanfilt,
    showunfound => \$showunfound,
    help => \$help,
) or pod2usage(2);
pod2usage(-verbose => 2) if $help;
pod2usage(3) unless (@ARGV or $cleanfilt);


my ($idfile) = shift;

# Read MITI output file of linkages, generated by lt2miti.
# TRACK_ID EPOCH_MJD RA_DEG DEC_DEG MAG OBSCODE OBJECT_NAME
# etc.
my %trktbl;             # all tracks created
my %mixed;
my %clean;
my %obsdata;            # table of obs count, days for clean objs

my %all_tracks;         # save these by track ID so we don't have to re-fetch from DB
my $line;


my ($orbit_id, $tracklet_id, $input_lineno);
my $last_orbit_id = '';


# Open LinkTracklets file and scan data.
my $stuffh = new FileHandle;
open $stuffh, $tracksfile or $mops_logger->logdie("can't open $tracksfile");

# Scan file and group lines by track ID.
my @t;
my %h;
my $i = 0;
while (defined($line = <$stuffh>)) {
    %h = miti_parse($line);
    push @{$all_tracks{$h{ID}}}, $line;                # save entire track line
    push @{$trktbl{$h{ID}}}, [@h{qw(ID OBJECT_NAME EPOCH_MJD)}];  # add entire line to entry for this ID
    $i++;
    print STDERR "$i\n" if $i % 50000 == 0;
}
$mops_logger->info(sprintf("Found %d tracks.", scalar keys %trktbl));
close $stuffh;

# OK, now scan each tracks.
foreach my $t (values %trktbl) {
    my %same;   # tally up different objects for orbit here
    my %mjds;   # count of different MJDs for these detections
    my $orbit_id;
    my $object_name;
    my $epoch_mjd;

    my $ndet = 0;
    foreach my $det (@{$t}) {
        ($orbit_id, $object_name, $epoch_mjd) = @{$det};
        $same{$object_name}++;
        $mjds{int($epoch_mjd)} = 1;
        $ndet++;
    }

    # For orbit to be counted as 'clean', require all same object and 3+ different MJDs.
    if (scalar keys %same == 1 and scalar keys %mjds > 2) {
        # All same
        $clean{$orbit_id} = $object_name;    # only key in hash
        $obsdata{$orbit_id} = {
            NOBS => scalar keys %mjds,
            NDET => $ndet
        }
    }
##    elsif (scalar keys %mjds > 2) {          # mixed w/sufficient obs
    else {
        $mixed{$orbit_id} = $orbit_id;
    }
}


if ($cleanfilt) {
    foreach my $key (sort keys %clean) {
        if ($clean{$key} =~ /^$cleanfilt/) {
            print $_ foreach @{$all_tracks{$key}};
        }
    }
}
else {
    # Now read list of IDs, and report the status of the track ID.
    my @ids = read_file($idfile);
    chomp @ids;
    my $obj;
    foreach my $id (@ids) {
        if (exists($clean{$id})) {
            printf "$id\tCLEAN\t%s\t%d\t%d\n", $clean{$id}, $obsdata{$id}->{NOBS}, $obsdata{$id}->{NDET};

            # Larry XXX: twiddle $clean here, so that when we're done, all
            # that's left of clean is unfound ones.
            delete $clean{$id};
        }
        elsif (exists($mixed{$id})) {
            printf "$id\tMIXED\t%s\n", $mixed{$id};
        }
    }

    if ($showunfound) {
        foreach my $key (keys %clean) {
            printf "$key\tUNFOUND\t%s\t%d\t%d\n", $clean{$key}, $obsdata{$key}->{NOBS}, $obsdata{$key}->{NDET};
        }
    }
}


=head1 DESCRIPTION

Tool to analyze quality of tracks and orbits and map track IDs to
object IDs.  There are several usage scenarios:

=over

=item 

Given a list of track IDs and a track file in MITI format, report whether
the track(s) found are "found", "unfound", or "bogus".

=back

Output:

track_id    status  object_id   [#days] [#obs]

If the track is CLEAN or UNFOUND, the number of days it appeared and number
of observations are reported.

If the track was MIXED, object_id is indeterminate so track_id is used in its place.

=head1 SYNOPSIS

trackTool [--tracks FILE] [--cleanfilt FILT] [--showunfound] 
    [--help] IDFILE

  --tracks FILE : read track identifications from file FILE
  --showunfound : report unfound tracks (in FILE but not IDFILE)
  --help : show man page
  idfile : file containing track IDs

=cut
