#!/usr/bin/env perl

use warnings;
use strict;
use File::Find;
use File::Basename;
use Cwd 'abs_path';
use Getopt::Attribute;
use YAML 'LoadFile';
use Template;


our $VERSION = '0.03';


my @smoke;

our @basedir : Getopt(dir=s);

# full filename for the topmost smoke html file
our $summary : Getopt(summary|s=s);

unless (@basedir) {
    @basedir = map { s/^~/$ENV{HOME}/; $_ } split /\s*;\s*/ => $ENV{PROJROOT};
}

unless (@basedir) {
    die "can't determine base dir (pass arg or set PROJROOT)\n";
}

unless (defined $summary) {
    $summary = "$basedir[0]/smoke.html";
}

my $summary_dir = abs_path(dirname($summary));

find (sub {
    return unless -f && $_ eq 'smoke.yaml';
    my $summary = LoadFile($_);

    unless ($summary->{distname}) {
        warn "$File::Find::name defines no distname\n";
        return;
    }

    # assume the summary_dir path is above all of the @basedir paths
    (my $rel_dir = $File::Find::dir) =~ s!^$summary_dir/!!;
    $summary->{link}    = "$rel_dir/smoke.html";

    my $tee = 'smoketee.txt';
    if (-e $tee) {
        $summary->{rawlink} = "$rel_dir/$tee";
        my $raw = do { local (@ARGV, $/) = $tee; <> };
        $summary->{rawalert}++ if
            $raw =~ /Use of uninitialized value/ ||
            $raw =~ / at .* line \d+/ ||
            $raw =~ /Failed test / ||
            $raw =~ /Looks like you failed/ ||
            $raw =~ /Looks like you planned \d+ tests but ran \d+ extra/ ||
            $raw =~ /No tests run!/;
    }

    my $coverage_html = "$File::Find::dir/cover_db/coverage.html";
    if (-e $coverage_html) {
        $summary->{coverage_link} = "$rel_dir/cover_db/coverage.html";

        open my $fh, $coverage_html or die "can't open $coverage_html: $!\n";
        my $html = do { local $/; <$fh> };
        close $fh or die "can't close $coverage_html: $!\n";

        # crude, but effective
        ($summary->{coverage_total}) = $html =~ m!">(\d+\.\d+)</td></tr>\D+$!s;
    }

    $summary->{coverage_total} = sprintf "%.2f",
        defined $summary->{coverage_total} ? $summary->{coverage_total} : 0;

    push @smoke => $summary;
}, @basedir);

@smoke =
    map  { $_->[0] }
    sort { $a->[1] cmp $b->[1] }
    map  { [ $_, $_->{distname} ] }
    @smoke;

my $template = do { local $/; <DATA> };
my $tt = Template->new;
$tt->process(\$template, { smoke => \@smoke }, $summary) || die $tt->error;

__DATA__
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
    "http://www.w3.org/TR/REC-html40/strict.dtd">
<html>
<head>
<title>Smoke Test Result Summary</title>

<script type="text/javascript" src="sorttable.js"></script>
<style type="text/css">
<!--

body {
    font-family: Verdana, Arial, Helvetica, Tahoma;
    font-size: small;
    background-color: #EFEFEF;
}

a { color: #000066; text-decoration: none; font-style: italic; }

table {
    border-collapse: collapse;
}

th, td {
    border: 1px solid #444444;
    font-weight: bold;
    font-size: 1em;
    color: black;
    text-align: center;
    vertical-align: middle;
    background-color: #efefef;
    padding: 5px;
}

td.allfail {
    background-color: #ff6450;
}

td.allpass {
    background-color: #00ff00;
}

td.partial {
    background-color: #fffb50;
}

-->
</style>

</head>
<body>
<h1>Smoke Test Result Summary</h1>

<table class="sortable" id="summary">
    <tr>
        <th id="0">Distribution</th>
        <th id="1">raw</th>
        <th id="2">coverage</th>
        <th id="3">tests</th>
        <th id="4">ok</th>
        <th id="5">fail</th>
        <th id="6">todo</th>
        <th id="7">skip</th>
        <th id="8">unexp.<BR>success</th>
        <th id="9">total</th>
        <th id="10">time</th>
    </tr>

[% FOR dist = smoke;
    IF dist.ratio == 0;
        tdclass = "allfail";
    ELSIF dist.ratio == 1;
        tdclass = "allpass";
    ELSE;
        tdclass = "partial";
    END;
%]
    <tr>
        <td>
            <a href="[% dist.link %]">[% dist.distname %]</a>
        </td>



        [% IF dist.rawlink %]

            [%
                IF dist.rawalert;
                    rawtdclass = "allfail";
                    rawtext    = "warn";
                ELSE;
                    rawtdclass = "allpass";
                    rawtext    = "ok";
                END;
            %]

            <td class="[% rawtdclass %]">
                <a href="[% dist.rawlink %]">[% rawtext %]</a>
            </td>
        [% ELSE %]
            <td class="allfail">MISSING</td>
        [% END %]



        [%
            IF dist.coverage_total + 0 == 0;
                covertdclass = "allfail";
            ELSIF dist.coverage_total + 0 == 100;
                covertdclass = "allpass";
            ELSE;
                covertdclass = "partial";
            END;
        %]

        <td class="[% covertdclass %]">
            [% IF dist.coverage_link %]
                <a href="[% dist.coverage_link %]">
            [% END %]
                    [% dist.coverage_total %]%
            [% IF dist.coverage_link %]
                </a>
            [% END %]
        </td>

        <td class="[% tdclass %]">[% dist.seen %]</td>
        <td class="[% tdclass %]">[% dist.passed %]</td>
        <td class="[% tdclass %]">[% dist.failed %]</td>
        <td class="[% tdclass %]">[% dist.todo %]</td>
        <td class="[% tdclass %]">[% dist.skipped %]</td>
        <td class="[% tdclass %]">[% dist.unexpectedly_succeeded %]</td>
        <td class="[% tdclass %]">[% dist.percentage %]</td>
        <td class="[% tdclass %]">[% dist.end_time %]</td>
    </tr>
[% END %]

</table>
</body>
</html>
