#!/bin/env perl

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

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::History;
use PS::MOPS::DC::SSM;
use PS::MOPS::DC::Iterator;
use PS::MOPS::Test::Instance;
use PS::MOPS::DC::Tracklet;
use PS::MOPS::DC::Orbit;
use PS::MOPS::DC::DerivedObject;
use PS::MOPS::Lib;
use PS::MOPS::Constants;

use PS::MOPS::DC::History::Derivation;
use PS::MOPS::DC::History::Attribution;
use PS::MOPS::DC::History::Precovery;
use PS::MOPS::DC::History::Identification;

# 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;

# 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=>0,
                                    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();

# make ssm object
our $g_ssm_obj1=PS::MOPS::DC::SSM->new($g_inst,
                                       e=>0,
                                       objectName=>"test_object_1",
                                       epoch=>0,
                                       timePeri=>0,
                                       argPeri=>0,
                                       node=>0,
                                       q=>0,
                                       i=>0,
                                       hV=>0
                                      );

# insert ssm object
modcs_insert($g_inst,$g_ssm_obj1);

# make history objects with various event types
our $g_h_derivation;
our $g_h_attribution;
our $g_h_precovery;
our $g_h_identification;

$g_h_derivation=
PS::MOPS::DC::History->new($g_inst,
                           derivedobjectId=>1,
                           eventType=>$EVENT_TYPE_DERIVATION,
                           fieldId=>1,
                           orbitId=>1,
                           orbitCode=>0,
                           classification=>0,
                           ssmId=>1 # not mandatory but used by functions
                          );

$g_h_attribution=
PS::MOPS::DC::History->new($g_inst,
                           derivedobjectId=>1,
                           eventType=>$EVENT_TYPE_ATTRIBUTION,
                           fieldId=>1,
                           orbitId=>1,
                           orbitCode=>0,
                           classification=>0,
                           ssmId=>1 # not mandatory but used by functions
                          );

$g_h_precovery=
PS::MOPS::DC::History->new($g_inst,
                           derivedobjectId=>1,
                           eventType=>$EVENT_TYPE_PRECOVERY,
                           fieldId=>1,
                           orbitId=>1,
                           orbitCode=>0,
                           classification=>0,
                           ssmId=>1 # not mandatory but used by functions
                          );

$g_h_identification=
PS::MOPS::DC::History->new($g_inst,
                           derivedobjectId=>1,
                           eventType=>$EVENT_TYPE_IDENTIFICATION,
                           fieldId=>1,
                           orbitId=>1,
                           orbitCode=>0,
                           classification=>0,
                           ssmId=>1 # not mandatory but used by functions
                          );

# insert db records
$g_h_derivation->record();
$g_h_attribution->record();
$g_h_precovery->record();
$g_h_identification->record();

# Test definition 1.
# create a history object
# Expected result: history object
#
# @return {1|0} Success is 1, failure is 0.
sub test_new
{
    my $success=0;
    $g_h=PS::MOPS::DC::History->new($g_inst,
                                    derivedobjectId=>1,
                                    eventType=>0,
                                    fieldId=>1,
                                    orbitId=>1,
                                    orbitCode=>0,
                                    classification=>0,
                                    ssmId=>1 # not mandatory but used by functions
                                    );
    if($g_h=~/PS::MOPS::DC::History/){$success=1;}
    return $success;
}

# Test definition 2.
# record a history event
# Expected result: history record is created
#
# @return {1|0} Success is 1, failure is 0.
sub record
{
    my $success=0;
    $g_h->record();
    my $row=modch_retrieve($g_inst,
                           eventId=>1);
    if($row=~/PS::MOPS::DC::History/){$success=1;}

    # @todo verify more fields in the history object

    return $success;
}

# Test definition 3.
# retrieve a history record
# Expected result: history object created from history record
#
# @return {1|0} Success is 1, failure is 0.
sub modch_retrieve__eventId
{
    my $success=0;
    my $row=modch_retrieve($g_inst,
                           eventId=>1);
    if($row=~/PS::MOPS::DC::History/){$success=1;}
    return $success;
}

# Test definition 4.
# retrieve a history record
# Expected result: history object created from history record
#
# @return {1|0} Success is 1, failure is 0.
sub modch_retrieve__ssmId__fieldId
{
    my $success=0;
    my $row=modch_retrieve($g_inst,
                           ssmId=>1,
                           fieldId=>1);
    if($row=~/PS::MOPS::DC::History/){$success=1;}
    return $success;
}

# @todo test different event types during retrieval
# this would effectively test modchd_retrieve(), modcha_retrieve(), modchp_retrieve() and modchi_retrieve().

# Test definition 5.
# retrieve a history record
# Expected result: history object created from history record
#
# @return {1|0} Success is 1, failure is 0.
sub modch_retrieve__derivedobjectId
{
    my $success=0;

    # retrieve a history object given a derived object ID
    # the history class has a number of subclasses

    my $row=modch_retrieve($g_inst,
                           derivedobjectId=>1);

    if($row=~/PS::MOPS::DC::History/){$success=1;}
    return $success;
}

sub modch_retrieve__derivedobjectId__attribution
{}

sub modch_retrieve__derivedobjectId__precovery
{}

sub modch_retrieve__derivedobjectId__identification
{}

# not implemented in source
sub modch_retrieve__derivedobjectId__removal
{}

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

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

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

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

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

=skip

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

=cut
