#!/usr/bin/env perl

# Copyright (c) 2019 Christian Jaeger, copying@christianjaeger.ch
# This is free software. See the file COPYING.md that came bundled
# with this file.


# Run example snippets in POD sections.

# If there's an issue with those, run `DEBUG=1 t/pod_snippets` and
# look at the saved file!


use strict; use warnings; use warnings FATAL => 'uninitialized';

use Test::Requires qw(Test::Pod::Snippets Function::Parameters);
use Test::More;

use lib "./lib";
use lib "./meta";
use FunctionalPerl::ModuleList;
use Chj::Backtrace;

use lib "./htmlgen";

my %ignore= map{ $_=> 1}
  qw(
    Chj::Class::Array
    FP::DBI
    FP::Trie
    FP::Untainted
    FP::IOStream
    FP::Interfaces
    FP::Repl::AutoTrap
    Chj::Backtrace
    Chj::BinHexOctDec
    Chj::BuiltinTypePredicates
    Chj::CPAN::ModulePODUrl
    Chj::Class::methodnames
    Chj::HTTP::Daemon
    Chj::IO::Command
    Chj::IO::CommandCommon
    Chj::IO::Dir
    Chj::IO::File
    Chj::IO::Pipe
    Chj::IO::PipelessCommand
    Chj::IO::Tempfile
    Chj::IO::WrappedFile
    Chj::Linux::LmSensors
    Chj::NamespaceClean
    Chj::NamespaceCleanAbove
    Chj::Package::OfPath
    FP::Repl::Repl
    FP::Repl::Dependencies
    FP::Repl::Stack
    FP::Repl::StackPlus
    FP::Repl::corefuncs
    Chj::Serialize
    Chj::TerseDumper
    FP::Repl::Trap
    Chj::Unix::Exitcode
    Chj::Unix::Signal
    Chj::Util::AskYN
    FP::Repl::WithRepl
    Chj::chompspace
    Chj::constructorexporter
    Chj::pp
    FP::Repl
    Chj::ruse
    Chj::time_this
    Chj::xIOUtil
    Chj::xhome
    Chj::xopen
    Chj::xopendir
    Chj::xoutpipe
    Chj::xperlfunc
    Chj::xpipe
    Chj::xtmpfile
   );

my $modules= modulenamelist;
#my $modules= [qw(FP::Equal FP::Ops)];

# plan tests=> scalar @$modules;
#  nope, when running direct, each module contributes its own number of
#  tests, not 1.

sub save {
    my ($module, $code)= @_;
    my $file= "tps-$module.pl";
    unlink $file;
    # XX possibly remove line directives from $code.
    open my $out, ">", $file or die "$file: $!";
    print $out $code or die $!;
    close $out or die $!;

    if ($ENV{DEBUG}) {
        print "=== Running again as expanded file '$file' and with FP::Repl::Trap..\n";
        system("perl", "-Mlib=./lib", "-MFP::Repl::Trap", $file);
        exit 1
    }
}

sub numfailures {
    my @failures= grep {
        not $_->{ok}
    } @{ Test::Builder->new->{Test_Results} };
    #warn "failures: @failures";
    scalar @failures
}

my $namespacenum= 0;

for (@$modules) {
    if ($ignore{$_}) {
        print "=== Ignoring pod snippets in $_.\n";
    } else {
        print "=== Running pod snippets in $_ ..\n";

        my $tps_direct = Test::Pod::Snippets->new();
        my $fail_before= numfailures;
        my $code= $tps_direct->generate_test( module => $_ );
        $code=~ s/(;\s*)no warnings;/${1};/;
        $code=~ s/(;\s*)no strict;/${1}use strict;/;
        $namespacenum++;
        if (eval "package t_pod_snippets_$namespacenum; $code; \n1") {
            my $fail_after= numfailures;
            if ($fail_after == $fail_before) {
                # done_testing("snippets in $_") but that's part of $code
            } else {
                fail("pod snippets in $_");
                save $_, $code;
            }
        } else {
            warn "Exception: $@\n";
            fail("pod snippets in $_");
            save $_, $code;
        }
    }
}

done_testing();
