#!/usr/bin/perl

use strict;
use warnings;

use IPC::System::Simple qw(capturex);
use Games::Solitaire::Verify::Solution;

if ($ARGV[0] =~ m{\A-h|--help\z})
{
    print <<'EOF';
summarize-fc-solve [Freecell Solver Args]

Display the solution status, the iterations count and the solution length
of the Freecell Solver invocation specified by the arguments. Also verifies
that the solution is true.

The "-g" flag to fc-solve is also used to determine the variant used by the
solution verifier.
EOF
    exit (0);
}

my @fc_solve_args = @ARGV;

my $variant = "freecell";
my $candidate;

FIND_VARIANT:
foreach my $arg (reverse(@fc_solve_args))
{
    if ($arg eq "-g")
    {
        $variant = $candidate;
        last FIND_VARIANT;
    }
    else
    {
        $candidate = $arg;
    }
}

my $fc_solve_output = capturex(qw(fc-solve -p -t -sam -sel), @fc_solve_args);

sub _line_found
{
    my ($s) = @_;

    return (($fc_solve_output =~ m{^\Q$s\E}ms) ? 1 : 0);
}

my $is_solvable = _line_found('This game is solveable');
my $unsolved = _line_found('I could not solve');
my $intractable = _line_found('Iterations count exceeded');

my @true = (grep { $_ } ($is_solvable, $unsolved, $intractable));

if (! (@true == 1))
{
    die "Game is more than one of solved, unsolvable or intractable!";
}

if ($is_solvable)
{
    open my $input_fh, "<", (\$fc_solve_output)
        or die "Cannnot open fc_solve_output.";
    my $solution = Games::Solitaire::Verify::Solution->new(
        {
            input_fh => $input_fh,
            variant => $variant,
        },
    );

    my $verdict = $solution->verify();

    close($input_fh);

    if ($verdict)
    {
        # require Data::Dumper;
        # die "Verdict == " . Dumper($verdict);
        die "Invalid solution!";
    }
}

my ($num_iters) = ($fc_solve_output =~ m{^Total number of states checked is (\d+)\.$}ms);
my $sol_len = () = ($fc_solve_output =~ m{^Move}msg);

print "Verdict: " .
    ($is_solvable ? "Solved"
        : $intractable ? "Intractable"
        : "Unsolved"
    )
    . " ; Iters: $num_iters ; Length: $sol_len\n";
