<%perl>
# simtest-results.html
#
# @author D. Chang
</%perl>

<%args>
$test_run_id
</%args>

<%perl>
# @todo Employ PS::MOPS::Test::Simulation::Utility for utility functions used within.
# @todo Employ PS::MOPS::Test::Simulation::DataHandler for database operations within.

use PS::MOPS::Lib;
use DBI;
#use PS::MOPS::Test::Simulation::Utility qw(getHMSString);
use PS::MOPS::Test::Utility qw(getHMSString);

my $simtest_id;
my $simrun_id;
my $ocnums_ref;
my $simtest_config_filename;

my $dbuser="root";
my $dbpass="panstar1";
#my $dbuser="mops";
#my $dbpass="mops";
my $dbname="psmops_testing_results";
my $dbhost="schmopc01.ifa.hawaii.edu";
my $dbconnect="DBI:mysql:$dbname:$dbhost";
my $dbh=DBI->connect($dbconnect,$dbuser,$dbpass) || die "ERROR: Cannot connect to database $dbname.";
my $sql="SELECT id,test_run,number,psmops_function,module,cvs_version,test,modifier1,modifier2,result,FORMAT(wall,5),cpu FROM simtest_results WHERE test_run=$test_run_id";
my $sth=$dbh->prepare($sql);
my $result=$sth->execute;
my $ref;
if($result){
    $ref=$sth->fetchall_arrayref();
}

# Get Test Run time.
$sql="SELECT DATE_FORMAT(time,'%Y-%b-%d %a %H:%i')
      FROM test_runs
      WHERE id=$test_run_id";
$sth=$dbh->prepare($sql);
$result=$sth->execute;
my $test_run_time;
if($result){
    $test_run_time=$sth->fetchall_arrayref();
}

# Get Simrun day results.
$sql="SELECT id,simrun_id,mjd,cal_day,
             ocnum,available,found,unfound,
             unlinked,failed_iod,failed_od,synthetic,
             nonsynthetic,mixed,clean,bad
      FROM simrun_day_results";
$sth=$dbh->prepare($sql);
$result=$sth->execute;
my $simrun_day_results;
if($result){
    $simrun_day_results=$sth->fetchall_arrayref();
}

# Get simtest_id corresponding to test_run_id.
$sql="SELECT id 
      FROM simtest_results 
      WHERE test_run=$test_run_id";
$sth=$dbh->prepare($sql);
$result=$sth->execute;
my $simtest_ids_ref=$sth->fetchall_arrayref();
$simtest_id=$simtest_ids_ref->[0]->[0];

# Get simrun_id corresponding to simtest_id.

$sql="SELECT distinct srr.id 
      FROM simrun_day_results sdr
      INNER JOIN simrun_results AS srr ON srr.id=sdr.simrun_id
      WHERE srr.simtest_id=$simtest_id";
$sth=$dbh->prepare($sql);
$result=$sth->execute;
my $simrun_ids_ref;
if($result!=0E0){
    $simrun_ids_ref=$sth->fetchall_arrayref();
}
else {
    die "Simrun ID not found.";
}

# Get Simtest details.
$sql="SELECT test_runs.id, str.instance_name, str.ssm, str.survey, 
             str.configuration, str.simtest_config, str.id
      FROM test_runs
      INNER JOIN simtest_results str ON str.test_run=test_runs.id
      WHERE test_runs.id=$test_run_id";
$sth=$dbh->prepare($sql);
$result=$sth->execute;
my $simtest_details;
if($result){
    $simtest_details=$sth->fetchall_arrayref();
}
$simtest_config_filename=$simtest_details->[0]->[5];

# @todo Add support for multiple Simruns.
$simrun_id=$simrun_ids_ref->[0]->[0];

# Get Simrun results grouped by OC from table simrun_day_results.
$sql="SELECT ocnum,sum(available),sum(found),sum(unfound),sum(unlinked), 
             sum(failed_iod),sum(failed_od),sum(synthetic),sum(nonsynthetic),
             sum(mixed),sum(clean),sum(bad),sum(precov_avail),sum(precov_found),
             sum(precov_mixed),sum(precov_bad),sum(precov_nonsynth),
             sum(detections),sum(tracklets)
      FROM simrun_day_results
      WHERE simrun_id=$simrun_id
      GROUP BY ocnum
      ORDER BY ocnum";
$sth=$dbh->prepare($sql);
$result=$sth->execute;
my $simrun_oc_results;
if($result){
    $simrun_oc_results=$sth->fetchall_arrayref();
}

# Get performance results for the Simrun.
$sql="SELECT dt_wall,dt_cpu,lod_wall,lod_cpu,
             precov_wall,precov_cpu
      FROM simrun_results
      WHERE id=$simrun_id";
$sth=$dbh->prepare($sql);
$result=$sth->execute;
my $benchmarks; # Array reference to performance data.
if($result){
    $benchmarks=$sth->fetchall_arrayref();
}

# Read the content of a Simtest configuration file.
# Return a hash reference to the configuration data.
#
# @todo Validate section titles.
sub readSimtestConfig
{
    my($filename)=@_;
    my %config;
    my $section;
    my @content;
    open(FILE,"<$filename");
    while(<FILE>){
        s/#.*//; # Eliminate comments.
        next if /^(\s)*$/; # Ignore blank lines.
        push(@content,$_);
    }
    close(FILE);

    foreach my $line (@content){
        if($line=~/\[(.*)\]/){
            $section=lc($1);
            my @new_array=();
            # @note Hash key is formed from section title.
            $config{$section}=\@new_array;
        }
        else{
            chomp($line);
            push(@{$config{$section}},$line);
        }
    }
    return \%config;
}

sub getHTMLSimtestDescription
{
    my($config)=@_;
    my $t="<ul>";
    foreach my $line (@{$config->{description}}){
        if($line=~s/\*\s+//){
            $t.="<li>$line";
        }
    }
    $t.="</ul>";
    return $t;
}

our %result_hash;

sub getSimrunPassed
{
    my($simrun_id,$simtest_config_filename)=@_;
    use PS::MOPS::Test::Simulation::GoalAnalyzer;
    my $conf=analyzeSimrun($simrun_id,$simtest_config_filename);
    my $passed=0;
    for(my $i=0;$i<scalar(@{$conf->{goals}});$i++){
        # Determine if current goal was PASS.
        if($conf->{'goals passed'}->[$i]==1){
            $passed++;
        }
    }
    return $passed;
}

sub getHTMLSimrunGoals
{
    my($simrun_id,$simtest_config_filename)=@_;
    use PS::MOPS::Test::Simulation::GoalAnalyzer;
    # @todo Retrieve analysis results from database instead of analyzing at runtime.
#    my $conf=analyzeSimrun($simrun_id,$simtest_config_filename);
    my $conf=analyzeSimrun($simrun_id);
    my $t="<ol>";
    for(my $i=0;$i<scalar(@{$conf->{goals}});$i++){
        # Determine if current goal was PASS.
        my $result=$conf->{'goals passed'}->[$i];
        $t.="<li>";
        my $goal_text=$conf->{goals}->[$i];
        if($goal_text=~s/\</\&lt;/g){}
        if($result==1){
            $t.="<font color=\"#006600\">$goal_text</font>";            
        } else {
            $t.="<font color=\"#cc0000\"><b>$goal_text</b></font>";
        }       
    }
    $t.="</ol>";
    return $t;
}

# @todo Read simtest config filename from database.
my $simtest_config_filepath="/usr/local/MOPS_DEV/testing-config/simtests";
my $simtest_config=readSimtestConfig("$simtest_config_filepath/$simtest_config_filename");
my $simtest_description=getHTMLSimtestDescription($simtest_config);


# Initialize sums of quantities.
my %sum;
our %result_sum;
$sum{derived_avail}=0;
$sum{derived_linked}=0;
$sum{derived_passiod}=0;
$sum{derived_passod}=0;
$sum{derived_mixed}=0;
$sum{derived_bad}=0;
$sum{derived_nonsynthetic}=0;
$sum{precov_avail}=0;
$sum{precov_found}=0;
$sum{precov_mixed}=0;
$sum{precov_bad}=0;
$sum{precov_nonsynth}=0;
$sum{detections}=0;
$sum{tracklets}=0;
$sum{wall}=0;
$sum{cpu}=0;

$result_sum{derived_avail}=0;
$result_sum{derived_linked}=0;
$result_sum{derived_passiod}=0;
$result_sum{derived_passod}=0;
$result_sum{derived_mixed}=0;
$result_sum{derived_bad}=0;
$result_sum{derived_nonsynthetic}=0;
$result_sum{precov_avail}=0;
$result_sum{precov_found}=0;
$result_sum{precov_mixed}=0;
$result_sum{precov_bad}=0;
$result_sum{precov_nonsynth}=0;
$result_sum{detections}=0;
$result_sum{tracklets}=0;
$result_sum{wall}=0;
$result_sum{cpu}=0;

# Compute sums.
foreach my $oc_data (@$simrun_oc_results){
    $result_sum{detections}+=$oc_data->[17];
    $result_sum{tracklets}+=$oc_data->[18];
    $result_sum{derived_avail}+=$oc_data->[1];
    $result_sum{derived_linked}+=$oc_data->[1] - $oc_data->[4];
    $result_sum{derived_passiod}+=($oc_data->[1] - $oc_data->[4]) - $oc_data->[5];
    $result_sum{derived_passod}+=($oc_data->[1] - $oc_data->[4]) - $oc_data->[6];
    $result_sum{precov_avail}+=$oc_data->[12];
}

$result_sum{wall}+=$benchmarks->[0]->[0];
$result_sum{cpu}+=$benchmarks->[0]->[1];
$result_sum{wall}+=$benchmarks->[0]->[2];
$result_sum{cpu}+=$benchmarks->[0]->[3];
$result_sum{wall}+=$benchmarks->[0]->[4];
$result_sum{cpu}+=$benchmarks->[0]->[5];



sub getSimrunResults
{
#    my($config,$simrun_oc_results)=@_;
    my($config)=@_;
    my $result_master=0;
    foreach my $line (@{$config->{goals}}){
        if($line=~/dets=(.*)/){
            if($1==$result_sum{detections}){
                $result_master++;
                $result_hash{dets}->{pass}=1;
                $result_hash{dets}->{text}=$line;
            }
        }
        if($line=~/tlets=(.*)/){
            if($1==$result_sum{tracklets}){
                $result_master++;
                $result_hash{tlets}->{pass}=1;
                $result_hash{tlets}{text}=$line;
            }
        }
        if($line=~/linking=(.*)\%/){
            if($result_sum{derived_avail}!=0){
                if($result_sum{derived_linked}/$result_sum{derived_avail}==1){
                    $result_master++;
                    $result_hash{linking}->{pass}=1;
                    $result_hash{linking}->{text}=$line;
                }
            }
        }
        if($line=~/passiod=(.*)\%/){
            if($result_sum{derived_avail}!=0){
                if($result_sum{derived_passiod}/$result_sum{derived_avail}==1){
                    $result_master++;
                    $result_hash{passiod}->{pass}=1;
                    $result_hash{passiod}->{text}=$line;
                }
            }
        }
        if($line=~/passod=(.*)\%/){
            if($result_sum{derived_passod}/$result_sum{derived_avail}==1){
                $result_master++;
                $result_hash{passod}->{pass}=1;
                $result_hash{passod}->{text}=$line;
            }
        }
        if($line=~/precov_cnt=(.*)/){
            if($result_sum{precov_avail}==$1){
                $result_master++;
                $result_hash{precov_cnt}->{pass}=1;
                $result_hash{precov_cnt}->{text}=$line;
            }
        }
        if($line=~/sum_wall_time<(.*)/){
            if($result_sum{wall}<$1){
                $result_master++;
                $result_hash{sum_wall_time}->{pass}=1;
                $result_hash{sum_wall_time}->{text}=$line;
            }
        }

    }
    return $result_master;
}

sub formatPercent
{
    my($n)=@_;
    return sprintf("%.0f\%",$n*100);
}

</%perl>

<& header.mas &>
<tt>
<!-- Debugging data -->
% my $result_master=getSimrunResults($simtest_config,$simrun_oc_results);
%# my $simrun_goals=getHTMLSimrunGoals($simtest_config,$simtest_config_filename);
</tt>
<p>
<table width="100%">
<tr>
<td width="90%">
<h2>Simtest Results</h2>
</td>
<td width="10%" align="right">
</td>
</tr>
<tr>
<td>Test Run ID = <% $test_run_id %>, Simtest ID = <% $simtest_id %>, Time = <% $test_run_time->[0]->[0] %> GMT, <b>

% my $passed=getSimrunPassed($simrun_id,"/usr/local/MOPS_DEV/testing-config/simtests/$simtest_config_filename");
% my $total=scalar(@{$simtest_config->{goals}});
% if($passed/$total==1){
<font color="#007700">
% } else {
<font color="#dd0000">
% }

Result =

% print " $passed/$total";

</b>
</font>

</td>
</tr>
</table>
<p>

<!--
<tt>Debug data<br>
Simtest ID=<% $simtest_id %><br>
Det cnt=<% $simrun_oc_results->[17] %><br>
</tt>
-->


<table cellspacing="8">
<tr valign="top">
<td>
<h3>Test Description</h3>
<% $simtest_description %>
</td>
<td>
&nbsp;&nbsp;
</td>
<td>
<h3>Configuration</h3>
SSM = <% $simtest_config->{ssm}->[0] %><br>
Survey = <% $simtest_config->{survey}->[0] %><br>
Region = <% $simtest_config->{region}->[0] %><br>
PS-MOPS Configuration = <% $simtest_config->{'ps-mops config'}->[0] %><br>
</td>

</tr>
</table>

<h3>Simruns</h3>
<h4>Summary</h4>
<p>
Simrun ID = <% $simrun_id %>

<table border="0" cellspacing="12"><tr><td>

<table border="0" cellspacing="8">
<tr valign="TOP">

% my $simrun_goals=getHTMLSimrunGoals($simrun_id,"/usr/local/MOPS_DEV/testing-config/simtests/$simtest_config_filename");

<td bgcolor="#ffffcc">
<table border="1" cellpadding="6"><tr><td>
<b>Goals</b>
<% $simrun_goals %>
</td></tr></table>
</td>
<td>&nbsp;&nbsp;</td>

<td>


<table border="1">
<tr>
<td><b>OC</b></td>
<!-- <td><b>Result</b></td> -->
<td><b>Detections</b></td>
<td><b>Tracklets</b></td>
</tr>

% # Iterate over Simrun by OC results.
% foreach my $oc_data (@$simrun_oc_results){
<tr>
<td>
<% $oc_data->[0] %>
</td>
<!--
<td bgcolor="#009900">
PASS
</td>
-->
<td>
<% $oc_data->[17] %>
% $sum{detections}+=$oc_data->[17];
</td>
<td>
<% $oc_data->[18] %>
% $sum{tracklets}+=$oc_data->[18];
</td>
</tr>
% } # End foreach.
<tr>

<!--<td><b>Totals</b></td>
<td bgcolor="#009900">
100%
</td>
-->

<td>
<b>Totals</b>
</td>

<td><b><% $sum{detections} %></b></td>
<td><b><% $sum{tracklets} %></b></td>
</tr>

</table>

</td>
<td>

<table border="1">
<tr>

<td><b>Process</b></td>
<td><b>Wall</b></td>
<td><b>CPU</b></td>
</tr>

<tr>

<td>
<b>DT</b>
</td>
<td><% getHMSString($benchmarks->[0]->[0]) %></td>
% $sum{wall}+=$benchmarks->[0]->[0];
<td><% getHMSString($benchmarks->[0]->[1]) %></td>
% $sum{cpu}+=$benchmarks->[0]->[1];

</tr>
<tr>

<td>
<b>LOD</b>
</td>
<td><% getHMSString($benchmarks->[0]->[2]) %></td>
% $sum{wall}+=$benchmarks->[0]->[2];
<td><% getHMSString($benchmarks->[0]->[3]) %></td>
% $sum{cpu}+=$benchmarks->[0]->[3];

</tr>
<tr>

<td><b>Precov</b></td>
<td><% getHMSString($benchmarks->[0]->[4]) %></td>
% $sum{wall}+=$benchmarks->[0]->[4];
<td><% getHMSString($benchmarks->[0]->[5]) %></td>
% $sum{cpu}+=$benchmarks->[0]->[5];
</tr>
<tr>
<td><b>Totals</b></td>
<td><b><% getHMSString($sum{wall}) %></b></td>
<td><b><% getHMSString($sum{cpu}) %></b></td>
</tr>
</table>

</td>
<td>
&nbsp;
</td>

</tr>
</table>

<%perl>
# All the MJDs present in an OC are summed for the efficiencies.
</%perl>

<h4>Linking Efficiencies</h4>
<table border="1">
<tr>
<td><b>OC</b></td>
<!--<td><b>Result</b></td>-->
<td><b>Available</b></td>
<td><b>Linked</b></td>
<td><b>Pass IOD</b></td>
<td><b>Pass OD</b></td>
<td><b>Mixed</b></td>
<td><b>Bad</b></td>
<td><b>Nonsynthetic</b></td>
</tr>
<tr valign="TOP">

<%perl>
# For each OC of data, report the summary derived efficiency results.
</%perl>

% foreach my $oc_data (@$simrun_oc_results){
<tr>
<td>
<% $oc_data->[0] %>
</td>

<!--<td bgcolor="#009900">
PASS
</td>-->

<td>
<% $oc_data->[1] %>
% $sum{derived_avail}+=$oc_data->[1];
</td>
<td>

% # Linked = available - unlinked
<% $oc_data->[1] - $oc_data->[4] %>
% $sum{derived_linked}+=$oc_data->[1] - $oc_data->[4];

</td>
<td>
% # Pass IOD = linked - failed_iod
<% ($oc_data->[1] - $oc_data->[4]) - $oc_data->[5] %>
% $sum{derived_passiod}+=($oc_data->[1] - $oc_data->[4]) - $oc_data->[5];
</td>
<td>
% # Pass OD = linked - failed_od
<% ($oc_data->[1] - $oc_data->[4]) - $oc_data->[6] %>
% $sum{derived_passod}+=($oc_data->[1] - $oc_data->[4]) - $oc_data->[6];
</td>
<td>
% # Mixed.
<% $oc_data->[9] %>
% $sum{derived_mixed}+=$oc_data->[9];
</td>
<td>
% # Bad.
<% $oc_data->[11] %>
% $sum{derived_bad}+=$oc_data->[11];
</td>
<td>
% # Nonsynthetic.
<% $oc_data->[8] %>
% $sum{derived_nonsynthetic}+=$oc_data->[8];
</td>
</tr>
% } # End foreach.
<tr>
<td><b>Totals</b></td>
<!--<td bgcolor="#009900"><b>100%</b></td>-->
<td><b><% $sum{derived_avail} %></b></td>
<td><b><% $sum{derived_linked} %></b> &nbsp;<font color="#666666" size="-1">(<% formatPercent($sum{derived_linked}/$sum{derived_avail}) %>)</font></td>
<td><b><% $sum{derived_passiod} %></b> &nbsp;<font color="#666666" size="-1">(<% formatPercent($sum{derived_passiod}/$sum{derived_avail}) %>)</font></td>
<td><b><% $sum{derived_passod} %></b> &nbsp;<font color="#666666" size="-1">(<% formatPercent($sum{derived_passod}/$sum{derived_avail}) %>)</font></td>
<td><b><% $sum{derived_mixed} %></b></td>
<td><b><% $sum{derived_bad} %></b></td>
<td><b><% $sum{derived_nonsynthetic} %></b></td>
</tr>

</table>

<h4>Precoveries</h4>
<table border="1">
<tr>
<td><b>OC</b></td>
<!--<td><b>Result</b></td>-->
<td><b>Available</b></td>
<td><b>Found</b></td>
<td><b>Mixed</b></td>
<td><b>Bad</b></td>
<td><b>Nonsynthetic</b></td>
</tr>

% foreach my $oc_data (@$simrun_oc_results){
<tr>
<td>
<% $oc_data->[0] %>
</td>
<!--<td bgcolor="#009900">
PASS
</td>-->
<td>
<% $oc_data->[12] %>
% $sum{precov_avail}+=$oc_data->[12];
</td>
<td>
<% $oc_data->[13] %>
% $sum{precov_found}+=$oc_data->[13];
</td>
<td>
<% $oc_data->[14] %>
% $sum{precov_mixed}+=$oc_data->[14];
</td>
<td>
<% $oc_data->[15] %>
% $sum{precov_bad}+=$oc_data->[15];
</td>
<td>
<% $oc_data->[16] %>
% $sum{precov_nonsynth}+=$oc_data->[16];
</td>

</tr>
% } # End foreach.
<tr>
<td><b>Totals</b></td>
<!--<td bgcolor="#009900"><b>100%</b></td>-->
<td><b><% $sum{precov_avail} %></b></td>
<td><b><% $sum{precov_found} %></b></td>
<td><b><% $sum{precov_mixed} %></b></td>
<td><b><% $sum{precov_bad} %></b></td>
<td><b><% $sum{precov_nonsynth} %></b></td>
</tr>




</table>

</td></tr></table>
<p>
<font size="-1"><b>Notes</b> A Simtest consists of one or more Simruns. A Simrun spans one or more lunations.</font>
</p>
</body>
</html>
