#!/bin/env perl

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

# This test uses the assumption that in a blank DB, autoincrements ids will go in the order 1, 2, 3, 4...

use strict;

use Benchmark ':hireswallclock';

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

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

# 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_fld=0; # test field
our $g_retr_fld=0; # field for testing retrieval

our $g_det1; # Test Detection.
our $g_det2; # Test Detection.
our $g_det3; # Test Detection.

# Test definition 1.
# Test the constructor.
# Expected result: A Field object.
#
# @return {1|0} Success is 1, failure is 0.
sub test_new
{
    my $success=0;

    my @de=(0,0,0,0,0,0,0,0,0,0);
    $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=>\@de,
                                    decSigma=>0,
                                    ra=>0,
                                    timeStart=>0,
                                    obscode=>0,
                                    limitingMag=>0
        );
    if($g_fld=~/PS::MOPS::DC::Field/){ $success=1; }
    return $success;
}

# Test definition 2.
# Retrieve a field record from the DB.
# Expected result: A Field object.
#
# @return {1|0} Success is 1, failure is 0.
sub test_modcf_retrieve
{
    my $success=0;
    $g_fld->insert();
    $g_retr_fld=modcf_retrieve($g_inst,fieldId=>1);
    if($g_retr_fld=~/PS::MOPS::DC::Field/){ $success=1; }
    return $success;
}

# Test definition 3.
# Delete a field given a field ID.
# Expected result: DB record is deleted.
#
# @return {1|0} Success is 1, failure is 0.
sub test_modcf_delete
{
    my $success=0;
    $g_fld->insert();
    modcf_delete($g_inst,
                 fieldId=>2);
    # See if the record is still in the db.
    $g_retr_fld=modcf_retrieve($g_inst,fieldId=>2);
    if($g_retr_fld=~/PS::MOPS::DC::Field/){ $success=0; }
    else { $success = 1; }
    return $success;
}

# Test definition 4.
# Insert the Field into the DB.
# Expected result: New DB record.
#
# @return {1|0} Success is 1, failure is 0.
sub test_insert
{
    my $success=0;
    $g_fld->insert();
    $g_retr_fld=modcf_retrieve($g_inst,fieldId=>3);
    if($g_retr_fld=~/PS::MOPS::DC::Field/){ $success=1; }
    return $success;
}

# Test definition 5.
# An interface to modcf_delete.
# Expected result: DB record is deleted.
#
# @return {1|0} Success is 1, failure is 0.
sub test_delete
{
    my $success=0;

    $g_fld->insert();
    $g_fld->delete(fieldId=>4);
    # See if the record is still in the db.
    $g_retr_fld=modcf_retrieve($g_inst,fieldId=>4);
    if($g_retr_fld=~/PS::MOPS::DC::Field/){ $success=0; }
    else { $success = 1; }

    return $success;
}

# Test definition 6.
# Set the status for the Field.
# Expected result: A status.
#
# @return {1|0} Success is 1, failure is 0.
sub test_status_set
{
    my $success=0;
    $g_fld->insert();
    $g_fld->status("Z"); # Set the status.
    if($g_fld->status() eq "Z"){ $success=1; }
    return $success;
}

# Test definition 7.
# The status for the Field is retrieved.
# Expected result: A status.
#
# @return {1|0} Success is 1, failure is 0.
sub test_status_get
{
    my $success=0;
    if($g_fld->status() eq "Z"){ $success=1; }
    return $success;
}

# Test definition 8.
#
# Expected result:
#
# @return {1|0} Success is 1, failure is 0.
sub test_parentId__set
{
    my $success=0;
    $g_fld->parentId("100");
    if($g_fld->parentId eq "100"){ $success=1; }
    return $success;
}

# Retrieve the parentId.
sub test_parentId__get
{
    my $success=0;
    $g_fld->parentId("101");
    if($g_fld->parentId eq "101"){ $success=1; }
    return $success;
}

# Test definition 9.
# Add multiple detections to a field
# With an array of Detections add them to the Field.
# Expected result: Multiple detections associated with a given field.
#
# @return {1|0} Success is 1, failure is 0.
sub test_addDetections
{
    my $success=0;

    # Create new detections.
    $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);

    my @dets = ($g_det1,$g_det2,$g_det3);

    # Add them to the field.
    $g_fld->addDetections(@dets);

    my $cnt=0;
    # iterate over detections and check to see that they were added to the correct field
    foreach my $d (@dets){
        if($d->{fieldId}==5){ $cnt++; }
    }
    if($cnt==3){
        $success=1;
    }
    return $success;
}

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

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

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

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

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

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

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

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

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

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

