#!/usr/bin/perl

eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
  if 0;    # not running under some shell

use strict;
use warnings;

sub _print;
use Getopt::Long;
use Term::ANSIColor;

GetOptions(
    'v|verbose' => \my $VERBOSE,
);

use TAPx::Parser;
use TAPx::Parser::Aggregator;
use TAPx::Parser::Source::Perl;

##############################################################################

=head1 NAME

tprove_color2 - Run tests with color.

=head1 USAGE

 tprove_color2 [ list of test files ]

=head1 DESCRIPTION

Try running this:

  perl -Ilib examples/tprove_color2 --verbose examples/t/*.t

=head1 CAVEATS

This is alpha code.  You've been warned.

=head1 TODO

Eventually throw on a TK interface just to let folks know what we can do.

=cut

use File::Find;
my @tests;
if (@ARGV) {
    @tests = @ARGV;
}
else {
    find( sub { -f && /\.t$/ && push @tests => $File::Find::name }, 't' );
}

my $aggregate = TAPx::Parser::Aggregator->new;
my $source    = TAPx::Parser::Source::Perl->new;
foreach my $test (@tests) {
    if ( my $stream = $source->filename($test)->get_stream ) {
        my $parser = analyze_test( $test, $stream );
        $aggregate->add( $test, $parser );
    }
    else {
        my $error = $source->error;
        warn "Could not run ($test): $error";
        next;
    }
}

my ( $total, $passed, $failed, $errors ) = (
    $aggregate->total,
    scalar $aggregate->passed,
    scalar $aggregate->failed,
    scalar $aggregate->parse_errors,
);

print <<"END_SUMMARY";
Tests run:  $total
Passed:     $passed
Failed:     $failed
Errors:     $errors
END_SUMMARY

sub analyze_test {
    my ( $test, $stream ) = @_;

    my $parser = TAPx::Parser->new( { stream => $stream } );
    print "$test......";
    while ( my $result = $parser->next ) {
        _print $result;
    }
    unless ( $parser->failed ) {
        print "ok\n";
    }
    else {
        print "not ok.\nFailed: @{[$parser->failed]}\n";
    }
    return $parser;
}

sub _print {
    return unless $VERBOSE;
    my $result = shift;
    if ( $result->is_test ) {
        if ( $result->passed && not $result->directive ) {
            print color 'green';
        }
        elsif ( !$result->passed ) {    # even if it's TODO
            print color 'white on_red';
        }
        elsif ( $result->has_skip ) {
            print color 'white on_blue';

        }
        elsif ( $result->has_todo ) {
            print color 'white';
        }
        print $result->as_string;
        print color 'reset';
        print "\n";
    }
    else {
        print $result->as_string, $/;
    }
}
