src/gleeam_code.erl

-module(gleeam_code).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeam_code.gleam").
-export([parse_global/1, version/0, usage/0, route/1, main/0]).
-export_type([global_opts/0, command/0]).

-type global_opts() :: {global_opts, binary()}.

-type command() :: version |
    init |
    auth |
    {list, list(binary())} |
    {fetch, binary()} |
    {test, binary()} |
    {submit, binary()}.

-file("src/gleeam_code.gleam", 24).
-spec parse_global(list(binary())) -> {global_opts(), list(binary())}.
parse_global(Args) ->
    case Args of
        [<<"-C"/utf8>>, Dir | Rest] ->
            {{global_opts, Dir}, Rest};

        _ ->
            {{global_opts, <<"."/utf8>>}, Args}
    end.

-file("src/gleeam_code.gleam", 85).
-spec version() -> binary().
version() ->
    gleeam_code_version_ffi:get_version().

-file("src/gleeam_code.gleam", 87).
-spec usage() -> binary().
usage() ->
    <<"glc - Gleam LeetCode CLI

Usage:
  glc init                    Initialize project
  glc auth                    Save LeetCode session cookie
  glc list [options]          List fetched problems
  glc fetch <slug-or-number>  Fetch problem and generate files
  glc test <slug-or-number>   Run tests for a problem
  glc submit <slug-or-number> Submit solution to LeetCode

List options:
  --easy, --medium, --hard    Filter by difficulty
  --solved, --unsolved        Filter by submission status"/utf8>>.

-file("src/gleeam_code.gleam", 31).
-spec route(list(binary())) -> {ok, command()} | {error, binary()}.
route(Args) ->
    case Args of
        [<<"--version"/utf8>>] ->
            {ok, version};

        [<<"-v"/utf8>>] ->
            {ok, version};

        [<<"init"/utf8>>] ->
            {ok, init};

        [<<"auth"/utf8>>] ->
            {ok, auth};

        [<<"list"/utf8>> | Rest] ->
            {ok, {list, Rest}};

        [<<"fetch"/utf8>>, Target] ->
            {ok, {fetch, Target}};

        [<<"test"/utf8>>, Target@1] ->
            {ok, {test, Target@1}};

        [<<"submit"/utf8>>, Target@2] ->
            {ok, {submit, Target@2}};

        [<<"fetch"/utf8>>] ->
            {error, <<"Missing argument: <slug-or-number>"/utf8>>};

        [<<"test"/utf8>>] ->
            {error, <<"Missing argument: <slug-or-number>"/utf8>>};

        [<<"submit"/utf8>>] ->
            {error, <<"Missing argument: <slug-or-number>"/utf8>>};

        _ ->
            {error, usage()}
    end.

-file("src/gleeam_code.gleam", 46).
-spec main() -> nil.
main() ->
    {Opts, Rest} = parse_global(erlang:element(4, argv:load())),
    case route(Rest) of
        {ok, version} ->
            gleam_stdlib:println(
                <<"glc "/utf8, (gleeam_code_version_ffi:get_version())/binary>>
            );

        {ok, init} ->
            case gleeam_code@init:run(
                erlang:element(2, Opts),
                fun gleam_stdlib:println/1
            ) of
                {ok, _} ->
                    nil;

                {error, Msg} ->
                    gleam_stdlib:println(<<"Error: "/utf8, Msg/binary>>)
            end;

        {ok, auth} ->
            case gleeam_code@auth:run(
                erlang:element(2, Opts),
                fun gleam_stdlib:println/1,
                fun gleeam_code_io_ffi:get_line/1
            ) of
                {ok, _} ->
                    nil;

                {error, Msg@1} ->
                    gleam_stdlib:println(<<"Error: "/utf8, Msg@1/binary>>)
            end;

        {ok, {list, Args}} ->
            case gleeam_code@list_cmd:run(
                erlang:element(2, Opts),
                Args,
                fun gleam_stdlib:println/1
            ) of
                {ok, _} ->
                    nil;

                {error, Msg@2} ->
                    gleam_stdlib:println(<<"Error: "/utf8, Msg@2/binary>>)
            end;

        {ok, {fetch, Target}} ->
            case gleeam_code@fetch:run(
                erlang:element(2, Opts),
                Target,
                fun gleam_stdlib:println/1
            ) of
                {ok, _} ->
                    nil;

                {error, Msg@3} ->
                    gleam_stdlib:println(<<"Error: "/utf8, Msg@3/binary>>)
            end;

        {ok, {test, Target@1}} ->
            case gleeam_code@test_cmd:run(
                erlang:element(2, Opts),
                Target@1,
                fun gleam_stdlib:println/1
            ) of
                {ok, _} ->
                    nil;

                {error, Msg@4} ->
                    gleam_stdlib:println(<<"Error: "/utf8, Msg@4/binary>>)
            end;

        {ok, {submit, Target@2}} ->
            case gleeam_code@submit:run(
                erlang:element(2, Opts),
                Target@2,
                fun gleam_stdlib:println/1
            ) of
                {ok, _} ->
                    nil;

                {error, Msg@5} ->
                    gleam_stdlib:println(<<"Error: "/utf8, Msg@5/binary>>)
            end;

        {error, Msg@6} ->
            gleam_stdlib:println(Msg@6)
    end.