#!/bin/env perl

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

use strict;

use Benchmark ':hireswallclock';

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

# Testing environment.
use Test::More tests=>5; # Perl testing framework.
use PS::MOPS::DC::DerivedObject;
use PS::MOPS::Test::Instance;
use PS::MOPS::DC::Detection;
use PS::MOPS::DC::Field;
use PS::MOPS::DC::Tracklet;
use PS::MOPS::DC::Orbit;

# 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_do1; # Test DerivedObject.
our $g_fld1; # Test Field.
our $g_det1; # Test Detection.
our $g_det2; # Test Detection.
our $g_det3; # Test Detection.
our $g_det4; # Test Detection.
our $g_tlet1; # Test Tracklet.
our $g_tlet2; # Test Tracklet.
our $g_orb1; # Test orbit.

my @de=(0,0,0,0,0,0,0,0,0,0);

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

# Insert field.
$g_fld1->insert();

$g_det1=PS::MOPS::DC::Detection->new($g_inst,
                                     mag=>0,
                                     dec=>0,
                                     ra=>0,
                                     epoch=>0,
                                     isSynthetic=>0,
                                     filter=>'w',
                                     s2n=>0);

$g_det2=PS::MOPS::DC::Detection->new($g_inst,
                                     mag=>0,
                                     dec=>0,
                                     ra=>0,
                                     epoch=>0,
                                     isSynthetic=>0,
                                     filter=>'w',
                                     s2n=>0);

$g_det3=PS::MOPS::DC::Detection->new($g_inst,
                                     mag=>0,
                                     dec=>0,
                                     ra=>0,
                                     epoch=>0,
                                     isSynthetic=>0,
                                     filter=>'w',
                                     s2n=>0);

$g_det4=PS::MOPS::DC::Detection->new($g_inst,
                                     mag=>0,
                                     dec=>0,
                                     ra=>0,
                                     epoch=>0,
                                     isSynthetic=>0,
                                     filter=>'w',
                                     s2n=>0);

# Insert detections.
$g_det1->addToField($g_fld1);
$g_det2->addToField($g_fld1);
$g_det3->addToField($g_fld1);
$g_det4->addToField($g_fld1);

# Create test Tracklets.
$g_tlet1=PS::MOPS::DC::Tracklet->new($g_inst,
                                     classification=>0,
                                     detections=>[$g_det1,$g_det2],
                                    );
$g_tlet2=PS::MOPS::DC::Tracklet->new($g_inst,
                                     classification=>0,
                                     detections=>[$g_det3,$g_det4],
                                    );

# Insert test tracklets.
$g_tlet1->insert();
$g_tlet2->insert();

$g_orb1=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 test orbit.
$g_orb1->insert();

sub test_new
{
    my $success=0;
    $g_do1=PS::MOPS::DC::DerivedObject->new($g_inst); # Passing g_inst here is critical.
    if($g_do1=~/PS::MOPS::DC::DerivedObject/){ $success=1; }

    # Insert the DO so that it has an ID.
    $g_do1->insert();

    # Attribute tracklets to this DO.
    $g_do1->attributeTracklets(TRACKLETS_AREF=>[$g_tlet1,$g_tlet2],
                               ORBIT=>$g_orb1); # Associate an arbitrary orbit to the DO.
                                                # This orbit is not connected to the tracklets
                                                # beforehand.
    return $success;
}

sub test_modcdo_retrieve
{
    my $success=0;
    return $success;
}

sub test_insert
{
    my $success=0;
    return $success;
}

# Test definition 1.
# Retrieve Detections associated with the DO.
# Uses Detection->modcd_retrieve().
#
# Expected result: Set of detections.
#
# @return {1|0} Success is 1, failure is 0.
sub test_fetchDetections
{
    my $success=0;
    my @dets=$g_do1->fetchDetections();
    if(scalar(@dets)==4) { $success=1; }
    return $success;
}

# Test definition 2.
# Retrieve Tracklets associated with the DO.
# Expected result: Set of Tracklets.
#
# @return {1|0} Success is 1, failure is 0.
sub test_fetchTracklets
{
    my $success=0;
    my @tlets=$g_do1->fetchTracklets();
    if(scalar(@tlets)==2) { $success=1; }
    return $success;
}

# Test definition 3.
# Retrieve an Orbit object associated with the DO.
# Expected result: An Orbit object.
#
# @return {1|0} Success is 1, failure is 0.
sub test_fetchOrbit
{
    my $success=0;
    my $orb=$g_do1->fetchOrbit();
    if($orb=~/PS::MOPS::DC::Orbit/){ $success=1; }
    return $success;
}

# Test definition 4.
# Retrieve the status for the DO.
# Expected result: DO status.
#
# @todo Test permutations of DO status.
#
# @return {1|0} Success is 1, failure is 0.
sub test_status
{
    my $success=0;
    my $s=$g_do1->status();
    if(!$s eq ""){ $success=1; }
    return $success;
}

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

# Perform test test_fetchDetections.
$g_start=new Benchmark;
ok(test_fetchDetections, "PS-MOPS-DC-DerivedObject->test_fetchDetections");
$g_end=new Benchmark;
print "time: PS-MOPS-DC-DerivedObject->test_fetchDetections: " . timestr(timediff($g_end,$g_start),'all') . "\n";

# Perform test test_fetchTracklets.
$g_start=new Benchmark;
ok(test_fetchTracklets, "PS-MOPS-DC-DerivedObject->test_fetchTracklets");
$g_end=new Benchmark;
print "time: PS-MOPS-DC-DerivedObject->test_fetchTracklets: " . timestr(timediff($g_end,$g_start),'all') . "\n";

# Perform test test_fetchOrbit.
$g_start=new Benchmark;
ok(test_fetchOrbit, "PS-MOPS-DC-DerivedObject->test_fetchOrbit");
$g_end=new Benchmark;
print "time: PS-MOPS-DC-DerivedObject->test_fetchOrbit: " . timestr(timediff($g_end,$g_start),'all') . "\n";

# Perform test test_status.
$g_start=new Benchmark;
ok(test_status, "PS-MOPS-DC-DerivedObject->test_status");
$g_end=new Benchmark;
print "time: PS-MOPS-DC-DerivedObject->test_status: " . timestr(timediff($g_end,$g_start),'all') . "\n";

