#!/bin/env perl

# This is a standalone testing executable for PS::MOPS::DC::History::Precovery.

use strict;

use Benchmark ':hireswallclock';

# Define variables for benchmarking.
our $g_start;
our $g_end;
our $g_diff;

# Testing environment.
use Test::More tests=>6; # Perl testing framework.
use PS::MOPS::Test::Instance;
use PS::MOPS::DC::History::Precovery;
use PS::MOPS::Constants qw($MOPS_EFF_CLEAN);
use PS::MOPS::DC::Field;
use PS::MOPS::DC::Tracklet;
use PS::MOPS::DC::Orbit;
use PS::MOPS::DC::DerivedObject;

# Make the PS-MOPS Instance available through $g_inst and
# the Test Instance available through $g_test_inst.
our $g_test_inst=PS::MOPS::Test::Instance->new();
our $g_inst=$g_test_inst->getPSMOPSInstance();

our $g_h_precov;

# create and insert related mops objects
# make orbits
our $g_o1=PS::MOPS::DC::Orbit->new($g_inst,
                                   e=>0,
                                   epoch=>0,
                                   timePeri=>0,
                                   argPeri=>0,
                                   node=>0,
                                   q=>0,
                                   i=>0,
                                   hV=>0,
                                   residual=>0);

# insert orbits
$g_o1->insert();

# make derived objects
our $g_do1=PS::MOPS::DC::DerivedObject->new($g_inst); # Passing g_inst here is critical.

# insert derived objects
$g_do1->insert();

# make field
our @g_de=(0,0,0,0,0,0,0,0,0,0);
our $g_fld=PS::MOPS::DC::Field->new($g_inst,
                                    epoch=>50000,
                                    filter=>'w', # referential integrity enforced.
                                    timeStop=>0,
                                    dec=>0,
                                    raSigma=>0,
                                    surveyMode=>0,
                                    de=>\@g_de,
                                    decSigma=>0,
                                    ra=>0,
                                    timeStart=>0,
                                    obscode=>0,
                                    limitingMag=>0);

# insert field
$g_fld->insert();

# detections
our $g_d1; # detection
our $g_d2; # detection

$g_d1=PS::MOPS::DC::Detection->new($g_inst,
                                   objectName=>"test object 1",
                                   mag=>0,
                                   dec=>0,
                                   ra=>0,
                                   epoch=>'56000',
                                   isSynthetic=>0,
                                   filter=>'w', # value enforced by ref integrity
                                   s2n=>0,
                                   fieldId=>1
                                  );

$g_d2=PS::MOPS::DC::Detection->new($g_inst,
                                   objectName=>"test object 2",
                                   mag=>0,
                                   dec=>0,
                                   ra=>0,
                                   epoch=>'56001',
                                   isSynthetic=>0,
                                   filter=>'w', # value enforced by ref integrity
                                   s2n=>0,
                                   fieldId=>1
                                  );

$g_d1->addToField($g_fld); # detection is added to the db.
$g_d2->addToField($g_fld); # detection is added to the db.

# tracklets
our @g_dets=($g_d1,$g_d2);
our $g_t1=PS::MOPS::DC::Tracklet->new($g_inst,
                                      detections=>\@g_dets,
                                      fieldId=>1,
                                      classification=>$MOPS_EFF_CLEAN);

$g_t1->insert();

our @g_tracklet_ids=(1);

# Test definition 1.
# create new object
# Expected result: history precovery object
#
# @return {1|0} Success is 1, failure is 0.
sub test_new
{
    my $success=0;

    # trackletId is required during record() but is not mandatory by the module
    # ephemeris_distance cannot be null

    $g_h_precov=PS::MOPS::DC::History::Precovery->new($g_inst,
                                                      derivedobjectId=>1,
                                                      fieldId=>1,
                                                      orbitId=>1,
                                                      orbitCode=>1,
                                                      trackletId=>1,
                                                      classification=>$MOPS_EFF_CLEAN,
                                                      ephemerisDistance=>0
                                                      );
    if($g_h_precov=~/PS::MOPS::DC::History::Precovery/){$success=1;}
    return $success;
}

# Test definition 2.
# insert db record
# Expected result: db record
#
# @return {1|0} Success is 1, failure is 0.
sub test_record
{
    my $success=0;
    $g_h_precov->record();
    my $result=modchp_retrieve($g_inst,
                               eventId=>1);
    if($result=~/PS::MOPS::DC::History::Precovery/){$success=1;}
    return $success;
}

# Test definition 3.
# retrieve db record as object
# Expected result: history precovery object
#
# @return {1|0} Success is 1, failure is 0.
sub modchp_retrieve__eventId
{
    my $success=0;
    my $result=modchp_retrieve($g_inst,
                               eventId=>1);
    if($result=~/PS::MOPS::DC::History::Precovery/){$success=1;}
    return $success;
}

sub modchp_retrieve__epoch_mjd
{
    my $success=0;
    my $result=modchp_retrieve($g_inst,
                               epoch_mjd=>50000);
    # result is an array reference
    # array should contain 1 member
    if($result->[0]=~/PS::MOPS::DC::History::Precovery/){$success=1;}
    return $success;
}

sub modchp_retrieve__fieldId
{
    my $success=0;
    my $result=modchp_retrieve($g_inst,
                               fieldId=>1);
    # result is an array reference
    # array should contain 1 member
    if($result->[0]=~/PS::MOPS::DC::History::Precovery/){$success=1;}
    return $success;
}

sub modchp_retrieve__empty
{
    my $success=0;
    my $result=modchp_retrieve($g_inst);
    # undef is expected as return value
    if($result eq ""){$success=1;}
    return $success;
}

# Test 1: test_new.
$g_start=new Benchmark;
ok(test_new, "PS-MOPS-DC-History-Precovery->test_new");
$g_end=new Benchmark;
print "time: PS-MOPS-DC-History-Precovery->test_new: " . timestr(timediff($g_end,$g_start),'all') . "\n";

# Test 2: test_record.
$g_start=new Benchmark;
ok(test_record, "PS-MOPS-DC-History-Precovery->test_record");
$g_end=new Benchmark;
print "time: PS-MOPS-DC-History-Precovery->test_record: " . timestr(timediff($g_end,$g_start),'all') . "\n";

# Test 3: modcha_retrieve.
$g_start=new Benchmark;
ok(modchp_retrieve__eventId, "PS-MOPS-DC-History-Precovery->modchp_retrieve__eventId");
$g_end=new Benchmark;
print "time: PS-MOPS-DC-History-Precovery->modchp_retrieve__eventId: " . timestr(timediff($g_end,$g_start),'all') . "\n";

$g_start=new Benchmark;
ok(modchp_retrieve__epoch_mjd, "PS-MOPS-DC-History-Precovery->modchp_retrieve__epoch_mjd");
$g_end=new Benchmark;
print "time: PS-MOPS-DC-History-Precovery->modchp_retrieve__epoch_mjd: " . timestr(timediff($g_end,$g_start),'all') . "\n";

$g_start=new Benchmark;
ok(modchp_retrieve__fieldId, "PS-MOPS-DC-History-Precovery->modchp_retrieve__fieldId");
$g_end=new Benchmark;
print "time: PS-MOPS-DC-History-Precovery->modchp_retrieve__fieldId: " . timestr(timediff($g_end,$g_start),'all') . "\n";

$g_start=new Benchmark;
ok(modchp_retrieve__empty, "PS-MOPS-DC-History-Precovery->modchp_retrieve__empty");
$g_end=new Benchmark;
print "time: PS-MOPS-DC-History-Precovery->modchp_retrieve__empty: " . timestr(timediff($g_end,$g_start),'all') . "\n";
