<commit_before>use v6;
unit module Sixatra;

use Router::Boost::Method;
use Sixatra::Request;
use Sixatra::Connection;
need Crust::Response;

our $ROUTER = Router::Boost::Method.new;

multi sixatra-app (Str $package --> Callable) is export {
    use MONKEY-SEE-NO-EVAL;
    EVAL "use $package;";
    sixatra-app;
}

multi sixatra-app ( --> Callable) is export {
    return sub ($env) {
        my $req = Sixatra::Request.new($env);

        my $match = $ROUTER.match($req.method, $req.path-info);
        return 405, [], ['Method Not Allowed'] if $match<is-method-not-allowed>;
        with $match<stuff> {
            my $c = Sixatra::Connection.new(:$req, :params($match<captured>));
            given $match<stuff>.app.($c) {
                when Crust::Response { return .finalize }
                default { return $_ }
            }
        }
        return 404, [], ['Not Found'];
    };
}

my class RoutingStaff {
    has Callable $.app;
};

multi router(Array $methods, Str $path, Callable $app) is export {
    $ROUTER.add(@$methods, $path, RoutingStaff.new(:$app));
}

multi router(Str $method, Str $path, Callable $app) is export {
    router([$method], $path, $app);
}

sub get(Str $path, Callable $app) is export {
    router ["GET", "HEAD"], $path, $app;
}

sub post(Str $path, Callable $app) is export {
    router "POST", $path, $app;
}

=begin pod
<commit_msg>support Int and Str response<commit_after>use v6;
unit module Sixatra;

use Crust::Response;
use Router::Boost::Method;

use Sixatra::Request;
use Sixatra::Connection;

our $ROUTER = Router::Boost::Method.new;

multi sixatra-app (Str $package --> Callable) is export {
    use MONKEY-SEE-NO-EVAL;
    EVAL "use $package;";
    sixatra-app;
}

multi sixatra-app ( --> Callable) is export {
    return sub ($env) {
        my $req = Sixatra::Request.new($env);

        my $match = $ROUTER.match($req.method, $req.path-info);
        return 405, [], ['Method Not Allowed'] if $match<is-method-not-allowed>;
        with $match<stuff> {
            my $c = Sixatra::Connection.new(:$req, :params($match<captured>));
            my $res = $match<stuff>.app.($c);
            # If response is not Crust::Response, convert.
            if $res !~~ Crust::Response {
                given $res {
                    when Array { return $res; } # Seems raw PSGI Response
                    when Int { $res = Crust::Response.new(:status($res), :headers([]), :body([])); }
                    when Str { $res = Crust::Response.new(:status(200), :headers([]), :body([$res])); }
                    default { return 500, [], ['Unexpected response!']; }
                }
            }
            return $res.finalize;
        }
        return 404, [], ['Not Found'];
    };
}

my class RoutingStaff {
    has Callable $.app;
};

multi router(Array $methods, Str $path, Callable $app) is export {
    $ROUTER.add(@$methods, $path, RoutingStaff.new(:$app));
}

multi router(Str $method, Str $path, Callable $app) is export {
    router([$method], $path, $app);
}

sub get(Str $path, Callable $app) is export {
    router ["GET", "HEAD"], $path, $app;
}

sub post(Str $path, Callable $app) is export {
    router "POST", $path, $app;
}

=begin pod

{'fraction_non_alphanumeric': 0.16837846249610955, 'fraction_numerical': 0.006224712107065048, 'mean_word_length': 2.6857798165137616, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1495586', 'n_tokens_mistral': 1088, 'n_tokens_neox': 1049, 'n_words': 285}