#!/usr/bin/perl -w
# NAME: tidytest.pl
# AIM: Some tests for tidy
use strict;
use warnings;
use File::Basename;  # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] )
use Cwd;
use JSON;
use Data::Dumper;

my $os = $^O;
my $perl_dir = '/home/geoff/bin';
my $PATH_SEP = '/';
my $temp_dir = '/tmp';
if ($os =~ /win/i) {
    $perl_dir = 'C:\GTools\perl';
    $temp_dir = $perl_dir;
    $PATH_SEP = "\\";
}
unshift(@INC, $perl_dir);
require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n";
# log file stuff
our ($LF);
my $pgmname = $0;
if ($pgmname =~ /(\\|\/)/) {
    my @tmpsp = split(/(\\|\/)/,$pgmname);
    $pgmname = $tmpsp[-1];
}
my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt";
open_log($outfile);

# user variables
my $VERS = "0.0.5 2015-01-09";
my $load_log = 0;
my $in_file = '';
my $verbosity = 0;
my $out_file = '';
my $tidyexe = 'tidy5';
my $tidyin = $temp_dir.$PATH_SEP."temp".$PATH_SEP."temptidyin";
my $tidyout = $temp_dir.$PATH_SEP."temp".$PATH_SEP."temptidyout";
my $tidyerr = $temp_dir.$PATH_SEP."temp".$PATH_SEP."temptidyerr";
my $tidyparams = "-e -q --show-info no --show-body-only yes";

# ### DEBUG ###
my $debug_on = 1;
#my $def_file = 'F:\Projects\html5lib-tests\validator\attributes.test';
#my $def_file = 'F:\Projects\html5lib-tests\validator\style-scoped-attribute.test';
my $def_file = 'F:\Projects\html5lib-tests\validator\langattribute.test';
my @validate_tests = qw(
F:\Projects\html5lib-tests\validator\attributes.test
F:\Projects\html5lib-tests\validator\base-href-attribute.test
F:\Projects\html5lib-tests\validator\base-target-attribute.test
F:\Projects\html5lib-tests\validator\blockquote-cite-attribute.test
F:\Projects\html5lib-tests\validator\classattribute.test
F:\Projects\html5lib-tests\validator\contenteditableattribute.test
F:\Projects\html5lib-tests\validator\contextmenuattribute.test
F:\Projects\html5lib-tests\validator\dirattribute.test
F:\Projects\html5lib-tests\validator\draggableattribute.test
F:\Projects\html5lib-tests\validator\html-xmlns-attribute.test
F:\Projects\html5lib-tests\validator\idattribute.test
F:\Projects\html5lib-tests\validator\inputattributes.test
F:\Projects\html5lib-tests\validator\irrelevantattribute.test
F:\Projects\html5lib-tests\validator\langattribute.test
F:\Projects\html5lib-tests\validator\li-value-attribute.test
F:\Projects\html5lib-tests\validator\link-href-attribute.test
F:\Projects\html5lib-tests\validator\link-hreflang-attribute.test
F:\Projects\html5lib-tests\validator\link-rel-attribute.test
F:\Projects\html5lib-tests\validator\ol-start-attribute.test
F:\Projects\html5lib-tests\validator\starttags.test
F:\Projects\html5lib-tests\validator\style-scoped-attribute.test
F:\Projects\html5lib-tests\validator\tabindexattribute.test );

### program variables
my @warnings = ();
my $cwd = cwd();

sub VERB1() { return $verbosity >= 1; }
sub VERB2() { return $verbosity >= 2; }
sub VERB5() { return $verbosity >= 5; }
sub VERB9() { return $verbosity >= 9; }

sub show_warnings($) {
    my ($val) = @_;
    if (@warnings) {
        prt( "\nGot ".scalar @warnings." WARNINGS...\n" );
        foreach my $itm (@warnings) {
           prt("$itm\n");
        }
        prt("\n");
    } else {
        prt( "\nNo warnings issued.\n\n" ) if (VERB9());
    }
}

sub pgm_exit($$) {
    my ($val,$msg) = @_;
    if (length($msg)) {
        $msg .= "\n" if (!($msg =~ /\n$/));
        prt($msg);
    }
    show_warnings($val);
    close_log($outfile,$load_log);
    exit($val);
}


sub prtw($) {
   my ($tx) = shift;
   $tx =~ s/\n$//;
   prt("$tx\n");
   push(@warnings,$tx);
}

my $counter = 0;

sub parse_json($$) {
    my ($txt,$fil) = @_;
    my $json = JSON->new->allow_nonref;
    my $rh = $json->decode( $txt );
    if (!defined ${$rh}{tests}) {
        prt("NO 'tests' defined in file $fil!\n");
        return;
    }
    my $ra = ${$rh}{tests};
    my $cnt = scalar @{$ra};
    prt("Found $cnt tests in file $fil\n");
    my ($rh2,$i,$desc,$input,$fail,$i2,@arr,$ok,$in,$out,$err,$params,$line,$len);
    for ($i = 0; $i < $cnt; $i++) {
        $rh2 = ${$ra}[$i];
        $i2 = $counter + $i + 1;
        $ok = 0;
        if (defined ${$rh2}{description} && defined ${$rh2}{input}) {
            $desc = ${$rh2}{description};
            $input = ${$rh2}{input};
            if (defined ${$rh2}{'fail-if'}) {
                $fail = ${$rh2}{'fail-if'};
                $ok = 1;
            } elsif (defined ${$rh2}{'fail-unless'}) {
                $fail = ${$rh2}{'fail-unless'};
                $ok = 1;
            }
        } 
        if ($ok) {
            if (length($input)) {
                $in = $tidyin.$i2.'.html';
                $out = $tidyout.$i2.'.html';
                $err = $tidyerr.$i2.'.txt';
                $params = "-o $out -f $err";
                write2file("$input\n",$in);
                prt("\n$i2: Running '$tidyexe $tidyparams $params $in\n");
                if (open (TDY, "$tidyexe $tidyparams $params $in|")) {
                    close TDY;
                    if (open INF, "<$err") {
                        @arr = <INF>;
                        close INF;
                        my @arr2 = ();
                        foreach $line (@arr) {
                            chomp $line;
                            $line = trim_all($line);
                            $len = length($line);
                            next if ($len == 0);
                            next if ($line =~ /^Info:/);
                            push(@arr2,$line);
                        }
                        prt("Fragment: $input\n");
                        prt("Suggested: $fail\n");
                        prt("Got:\n");
                        prt(join("\n",@arr2)."\n");
                    } else {
                        prtw("WARNING: Failed to open $err!\n");
                    }
                } else {
                    pgm_exit(1,"ERROR: Failed to open '$tidyexe $tidyparams $params $in'!\n");
                }
            } else {
                prt("$i2: No input $desc, $fail\n");
            }
        } else {
            @arr = keys %{$rh2};
            $desc = join(" ",@arr);
            prt("Test $i2 is INVALID! Got keys $desc\n");
        }
    }
    $counter += $cnt;
}

sub process_in_file($) {
    my ($inf) = @_;
    if (! open INF, "<$inf") {
        pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); 
    }
    my @lines = <INF>;
    close INF;
    my $lncnt = scalar @lines;
    prt("Processing $lncnt lines, from [$inf]...\n");
    my $line = join("",@lines);
    parse_json($line,$inf);
}

sub process_list() {
    my ($file);
    foreach $file (@validate_tests) {
        process_in_file($file);
    }
}

#########################################
### MAIN ###
parse_args(@ARGV);
process_list();
###process_in_file($in_file);
pgm_exit(0,"");
########################################

sub need_arg {
    my ($arg,@av) = @_;
    pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av);
}

sub parse_args {
    my (@av) = @_;
    my ($arg,$sarg);
    my $verb = VERB2();
    while (@av) {
        $arg = $av[0];
        if ($arg =~ /^-/) {
            $sarg = substr($arg,1);
            $sarg = substr($sarg,1) while ($sarg =~ /^-/);
            if (($sarg =~ /^h/i)||($sarg eq '?')) {
                give_help();
                pgm_exit(0,"Help exit(0)");
            } elsif ($sarg =~ /^v/) {
                if ($sarg =~ /^v.*(\d+)$/) {
                    $verbosity = $1;
                } else {
                    while ($sarg =~ /^v/) {
                        $verbosity++;
                        $sarg = substr($sarg,1);
                    }
                }
                $verb = VERB2();
                prt("Verbosity = $verbosity\n") if ($verb);
            } elsif ($sarg =~ /^l/) {
                if ($sarg =~ /^ll/) {
                    $load_log = 2;
                } else {
                    $load_log = 1;
                }
                prt("Set to load log at end. ($load_log)\n") if ($verb);
            } elsif ($sarg =~ /^o/) {
                need_arg(@av);
                shift @av;
                $sarg = $av[0];
                $out_file = $sarg;
                prt("Set out file to [$out_file].\n") if ($verb);
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            $in_file = $arg;
            prt("Set input to [$in_file]\n") if ($verb);
        }
        shift @av;
    }

    if ($debug_on) {
        prtw("WARNING: DEBUG is ON!\n");
        if (length($in_file) ==  0) {
            $in_file = $def_file;
            prt("Set DEFAULT input to [$in_file]\n");
            $load_log = 1;
        }
    }
    if (length($in_file) ==  0) {
        pgm_exit(1,"ERROR: No input files found in command!\n");
    }
    if (! -f $in_file) {
        pgm_exit(1,"ERROR: Unable to find in file [$in_file]! Check name, location...\n");
    }
}

sub give_help {
    prt("$pgmname: version $VERS\n");
    prt("Usage: $pgmname [options] in-file\n");
    prt("Options:\n");
    prt(" --help  (-h or -?) = This help, and exit 0.\n");
    prt(" --verb[n]     (-v) = Bump [or set] verbosity. def=$verbosity\n");
    prt(" --load        (-l) = Load LOG at end. ($outfile)\n");
    prt(" --out <file>  (-o) = Write output to this file.\n");
}

# eof - template.pl
