#!/usr/bin/env perl

my $copyright = <<'COPYRIGHT';
# Copyright 2021-2023 by Christian Jaeger <ch@christianjaeger.ch>
# Published under the same terms as perl itself
COPYRIGHT

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

my ($email_full) = $copyright =~ / by ([^\n]*)/s;

my ($mydir, $myname);

BEGIN {
    $0 =~ /(.*?)([^\/]+)\z/s or die "?";
    ($mydir, $myname) = ($1, $2);
}

sub usage {
    print STDERR map {"$_\n"} @_ if @_;
    print "$myname

  Read copy-paste from repl ('fperl' script or other FP::Repl
  invocation) and print as a series of Chj::TEST 'TEST' statements.

  ($email_full)
";
    exit(@_ ? 1 : 0);
}

use lib "$mydir/../lib/";

use FP::RegexMatch
    qw(all_continuous_matches_whole all_continuous_matches1 fullmatching);
use FP::autobox;
use FP::Ops qw(the_method);
use Chj::xperlfunc qw(xprint);
use Chj::TEST;

#use FP::Repl::Trap;

use Getopt::Long;
our ($debug, $opt_repl);
GetOptions("debug" => \$debug, "repl" => \$opt_repl, "help" => sub {usage})
    or exit 1;

my $in = do { local $/; <> };
$in .= "\n" unless $in =~ /\n\z/;

package PFLANZE::Test {
    use FP::Struct ["input", "results"];

    # Includes the 0-case, too
    sub is_multiple_values($self) {
        $self->results->length != 1
    }

    sub string ($self, $force_multiple_values) {
        my $results = $self->results;
        if ($force_multiple_values or $results->length != 1) {
            my $input = $self->input;
            my $inp2  = $input =~ /;/ ? "do { $input }" : $input;
            "TEST { [ $inp2 ] } [ " . $results->strings_join(", ") . " ];\n"
        } else {
            "TEST { " . $self->input . " } " . $results->first . ";\n"
        }
    }
    _END_
}
PFLANZE::Test::constructors->import;

my $Namespace  = qr/[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*/s;
my $Prompt     = qr/${Namespace}>/s;
my $Result     = qr/\n\$VAR\d+ = (.*?); */s;
my $Invocation = qr/${Prompt}\s*(.*?)($Result*)\n/s;

sub matches($in) {
    my $a = fullmatching(\&all_continuous_matches_whole)->($in, $Invocation);
    $a->map(
        sub ($inv) {
            my ($input, $_results) = $inv =~ $Invocation or die "bug";
            my $results
                = fullmatching(\&all_continuous_matches1)->($_results, $Result);

            # use FP::Repl;repl;
            Test($input, $results)
        }
    )
}

TEST {
    my $in = q&main> all_matches1 "foo barO", qr/(o)/i
$VAR1 = [
          'o',
          'o',
          'O'
        ];
main> all_matches_whole "foo barO", qr/o/i
$VAR1 = [
          'o',
          'o',
          'O'
        ];
main> all_continuous_matches_whole "oOo barO", qr/o/i
$VAR1 = [
          'o',
          'O',
          'o'
        ];
$VAR2 = 3;
main> all_continuous_matches_whole "BoOo barO", qr/o/i
$VAR1 = [];
$VAR2 = 0;
    &;
    matches($in)->map(the_method "string", 0)->join("")
}
q&TEST { all_matches1 "foo barO", qr/(o)/i } [
          'o',
          'o',
          'O'
        ];
TEST { all_matches_whole "foo barO", qr/o/i } [
          'o',
          'o',
          'O'
        ];
TEST { [ all_continuous_matches_whole "oOo barO", qr/o/i ] } [ [
          'o',
          'O',
          'o'
        ], 3 ];
TEST { [ all_continuous_matches_whole "BoOo barO", qr/o/i ] } [ [], 0 ];
&;

TEST {
    my $in = q&main> extract_urls1 "foo"
main> extract_urls1 "<foo.ch>"
$VAR1 = 'foo.ch';
main> extract_urls1 "<foo.ch.ch>"
$VAR1 = 'foo.ch.ch';
main> extract_urls1 "<foo.ch.chh>"
$VAR1 = 'foo.ch';
main> extract_urls1 "<foo.chh>"
main> 
&;
    matches($in)->map(the_method "string", 0)->join("")
}
'TEST { [ extract_urls1 "foo" ] } [  ];
TEST { extract_urls1 "<foo.ch>" } \'foo.ch\';
TEST { extract_urls1 "<foo.ch.ch>" } \'foo.ch.ch\';
TEST { extract_urls1 "<foo.ch.chh>" } \'foo.ch\';
TEST { [ extract_urls1 "<foo.chh>" ] } [  ];
TEST { [  ] } [  ];
';

TEST {
    my $in = q&main> extract_urls1 "foo"
main> extract_urls1 "<foo.ch>"
$VAR1 = 'foo.ch';
main> extract_urls1 "<foo.ch.ch>"
$VAR1 = 'foo.ch.ch';
main> extract_urls1 "<foo.ch.chh>"
$VAR1 = 'foo.ch';
main> extract_urls1 "<foo.chh>"
main> 
&;
    matches($in)->map(the_method "string", 1)->join("")
}
'TEST { [ extract_urls1 "foo" ] } [  ];
TEST { [ extract_urls1 "<foo.ch>" ] } [ \'foo.ch\' ];
TEST { [ extract_urls1 "<foo.ch.ch>" ] } [ \'foo.ch.ch\' ];
TEST { [ extract_urls1 "<foo.ch.chh>" ] } [ \'foo.ch\' ];
TEST { [ extract_urls1 "<foo.chh>" ] } [  ];
TEST { [  ] } [  ];
';

if ($opt_repl) {
    require FP::Repl;
    FP::Repl::repl();
} else {
    my $matches               = matches($in);
    my $force_multiple_values = $matches->any(the_method "is_multiple_values");
    my $strs = $matches->map(the_method("string", $force_multiple_values));
    $strs = $strs->intersperse("----") if $debug;
    $strs->for_each(\&xprint);
}

#use Chj::ruse;
#use Chj::Backtrace;

