#!/usr/bin/env raku
use v6.d;

use Terminal::ANSIColor;

use IUtils;
use IUtils::Regexes;
use IUtils::Compiler;

# TODO: Add filtering for tests based on module/name
# TODO: Move some of this functionality into methods for the relevant structs
#| 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;
    my $total-failures = 0;
    for @runables -> $runable {
        my $package-failures = 0;
        # 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;
            my $test-module-name =
                colored($runable.ipkg.relative($basedir), 'magenta bold');
            say "{colored '*', 'yellow bold'} Testing $test-module-name";
            for $runable.tests.keys -> $module-name {
                my $module-failures = 0;
                my $module = $runable.tests{$module-name};
                next unless $module.tests.elems > 0;
                my $colored-module = colored $module-name, 'cyan bold';
                say "{colored '**', 'magenta bold'} Testing $colored-module"
                    .indent(2);
                for $module.tests -> $test {
                    $module-failures += 1 if $test.run: $module.source;
                }
                if $module-failures == 0 {
                   say "All $colored-module ".indent(4),
                       colored('tests passed', 'green underline');
                } else {
                   say "$module-failures $colored-module ".indent(4),
                       colored('tests failed', 'red bold underline');
                }
                $package-failures += $module-failures;
            }
            if $package-failures == 0 {
                say "All $test-module-name ".indent(2),
                    colored('tests passed', 'green underline');
            } else {
                say "$package-failures $test-module-name ".indent(2),
                    colored('tests failed', 'red bold underline');
            }
            $total-failures += $package-failures;
        }
    }
    say '';
    if $total-failures == 0 {
        say 'All ', colored('tests passed', 'green underline');
    } else {
        say $total-failures, ' ',  colored('tests failed', 'red bold underline');
    }
}