src/gleeam_code@fetch.erl

-module(gleeam_code@fetch).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeam_code/fetch.gleam").
-export([run/3]).

-file("src/gleeam_code/fetch.gleam", 82).
-spec try_with(
    {ok, GCV} | {error, GCW},
    fun((GCW) -> binary()),
    fun((GCV) -> {ok, nil} | {error, binary()})
) -> {ok, nil} | {error, binary()}.
try_with(Res, To_string, Next) ->
    case Res of
        {ok, Val} ->
            Next(Val);

        {error, Err} ->
            {error, To_string(Err)}
    end.

-file("src/gleeam_code/fetch.gleam", 93).
-spec ensure_dir(binary()) -> {ok, nil} | {error, binary()}.
ensure_dir(Path) ->
    case gleeam_code@internal@file:mkdir(Path) of
        {ok, _} ->
            {ok, nil};

        {error, Err} ->
            {error,
                <<"Failed to create directory: "/utf8,
                    (gleeam_code@internal@file:describe_error(Err))/binary>>}
    end.

-file("src/gleeam_code/fetch.gleam", 101).
-spec write_file(binary(), binary()) -> {ok, nil} | {error, binary()}.
write_file(Path, Content) ->
    case gleeam_code@internal@file:write(Path, Content) of
        {ok, _} ->
            {ok, nil};

        {error, Err} ->
            {error,
                <<"Failed to write file: "/utf8,
                    (gleeam_code@internal@file:describe_error(Err))/binary>>}
    end.

-file("src/gleeam_code/fetch.gleam", 10).
-spec run(binary(), binary(), fun((binary()) -> nil)) -> {ok, nil} |
    {error, binary()}.
run(Base_dir, Target, Print) ->
    Session = gleeam_code@internal@config:get_session(),
    try_with(
        gleeam_code@internal@leetcode:resolve_slug(Target, Session),
        fun gleeam_code@internal@leetcode:describe_error/1,
        fun(Slug) ->
            Print(
                <<<<"Fetching problem: "/utf8, Slug/binary>>/binary,
                    "..."/utf8>>
            ),
            try_with(
                gleeam_code@internal@leetcode:fetch_problem(Slug, Session),
                fun gleeam_code@internal@leetcode:describe_error/1,
                fun(Problem) ->
                    gleam@result:'try'(
                        gleeam_code@internal@spec_parser:parse_erlang_spec(
                            erlang:element(8, Problem)
                        ),
                        fun(Spec) ->
                            Module_name = gleeam_code@internal@spec_parser:format_module_name(
                                erlang:element(2, Problem),
                                erlang:element(3, Problem)
                            ),
                            Module_path = <<"solutions/"/utf8,
                                Module_name/binary>>,
                            Src_dir = <<<<Base_dir/binary, "/src/"/utf8>>/binary,
                                Module_path/binary>>,
                            Test_dir = <<<<Base_dir/binary, "/test/"/utf8>>/binary,
                                Module_path/binary>>,
                            gleam@result:'try'(
                                ensure_dir(Src_dir),
                                fun(_) ->
                                    gleam@result:'try'(
                                        ensure_dir(Test_dir),
                                        fun(_) ->
                                            Solution_content = gleeam_code@internal@codegen:generate_solution(
                                                erlang:element(2, Problem),
                                                erlang:element(4, Problem),
                                                erlang:element(3, Problem),
                                                erlang:element(5, Problem),
                                                Spec
                                            ),
                                            Outputs = gleeam_code@internal@codegen:extract_outputs(
                                                erlang:element(6, Problem)
                                            ),
                                            Test_content = gleeam_code@internal@codegen:generate_test(
                                                Module_path,
                                                Spec,
                                                erlang:element(9, Problem),
                                                Outputs
                                            ),
                                            gleam@result:'try'(
                                                write_file(
                                                    <<Src_dir/binary,
                                                        "/solution.gleam"/utf8>>,
                                                    Solution_content
                                                ),
                                                fun(_) ->
                                                    Print(
                                                        <<<<"  Created src/"/utf8,
                                                                Module_path/binary>>/binary,
                                                            "/solution.gleam"/utf8>>
                                                    ),
                                                    gleam@result:'try'(
                                                        write_file(
                                                            <<Test_dir/binary,
                                                                "/solution_test.gleam"/utf8>>,
                                                            Test_content
                                                        ),
                                                        fun(_) ->
                                                            Print(
                                                                <<<<"  Created test/"/utf8,
                                                                        Module_path/binary>>/binary,
                                                                    "/solution_test.gleam"/utf8>>
                                                            ),
                                                            Param_types = begin
                                                                _pipe = erlang:element(
                                                                    3,
                                                                    Spec
                                                                ),
                                                                _pipe@1 = gleam@list:map(
                                                                    _pipe,
                                                                    fun(P) ->
                                                                        erlang:element(
                                                                            3,
                                                                            P
                                                                        )
                                                                    end
                                                                ),
                                                                gleam@string:join(
                                                                    _pipe@1,
                                                                    <<","/utf8>>
                                                                )
                                                            end,
                                                            gleam@result:'try'(
                                                                write_file(
                                                                    <<Src_dir/binary,
                                                                        "/.glc_meta"/utf8>>,
                                                                    <<<<<<<<<<<<"entry_function="/utf8,
                                                                                            (erlang:element(
                                                                                                2,
                                                                                                Spec
                                                                                            ))/binary>>/binary,
                                                                                        "\nparams="/utf8>>/binary,
                                                                                    Param_types/binary>>/binary,
                                                                                "\nreturn_type="/utf8>>/binary,
                                                                            (erlang:element(
                                                                                4,
                                                                                Spec
                                                                            ))/binary>>/binary,
                                                                        "\n"/utf8>>
                                                                ),
                                                                fun(_) ->
                                                                    {ok, nil}
                                                                end
                                                            )
                                                        end
                                                    )
                                                end
                                            )
                                        end
                                    )
                                end
                            )
                        end
                    )
                end
            )
        end
    ).