#!/usr/bin/env raku
use v6.d;
use IUtils;
use IUtils::Regexes;
use IUtils::Compiler;

# TODO: Add filtering for tests based on module/name
#| Execute the tests in an idris project
multi MAIN(
    "test",
    Str $project-path?, #= Base directory of the project, defaults to $*CWD
) {
    # CD into the project path if needed
    chdir($project-path.IO.resolve: :completely) if $project-path;
    # Scan for our packages
    my @packages = scan-packages;
    # Collect runables
    my @runables = @packages.map: *.runnables;
    # Run the tests
    my $basedir = $*CWD;
    for @runables -> $runable {
        # Make sure the package is built
        pack-build $runable.ipkg.relative;
        # CD to the local directory to make sure idris can exec the expressions
        indir $runable.ipkg.parent, {
            next unless $runable.tests.elems > 0;
            say "** Testing {$runable.ipkg.relative: $basedir}";
            for $runable.tests.keys -> $module-name {
                my $module = $runable.tests{$module-name};
                next unless $module.tests.elems > 0;
                say "-- Testing $module-name".indent(2);
                for $module.tests -> $test {
                    try {
                        idris-exec $test, $module.source.relative;
                    }
                    if $! {
                        my $stdout = $1.err.lines.map(*.indent(8)).join("\n");
                        say "+ $test: FAIL".indent(4);
                        say "stdout:".indent(6);
                        $!.err.lines.map(*.indent(8)).join("\n");
                        say "stderr:".indent(6);
                        $!.err.lines.map(*.indent(8)).join("\n");
                        say "exit code: {$!.exit-code}"
                    } else {
                        say "+ $test: Pass".indent(4);
                    }
                }
            }
        }
    }
}