-module(users@signinup).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).

-export([sign_up/3]).
-export_type([sign_up_err/0]).

-type sign_up_err() :: username_taken |
    username_too_short |
    password_too_short |
    {sign_up_failed, binary()}.

-spec add_user_to_db(sqlight:connection(), binary(), binary()) -> {ok, nil} |
    {error, sign_up_err()}.
add_user_to_db(Conn, Username, Password) ->
    _pipe = Conn,
    _pipe@1 = db@user:add(_pipe, Username, Password, <<"default"/utf8>>),
    gleam@result:map_error(_pipe@1, fun(E) -> case E of
                username_taken ->
                    username_taken;

                {add_db_err, S} ->
                    {sign_up_failed, S}
            end end).

-spec get_user_from_db(sqlight:connection(), binary()) -> {ok,
        users@user:user()} |
    {error, sign_up_err()}.
get_user_from_db(Conn, Username) ->
    _pipe = Conn,
    _pipe@1 = db@user:get(_pipe, Username),
    gleam@result:map_error(_pipe@1, fun(E) -> case E of
                invalid_user ->
                    {sign_up_failed,
                        <<"Invalid User (THIS SHOULD BE IMPOSSIBLE)"/utf8>>};

                {get_db_err, S} ->
                    {sign_up_failed, S}
            end end).

-spec add_session_key_to_db(sqlight:connection(), integer(), binary()) -> {ok,
        nil} |
    {error, sign_up_err()}.
add_session_key_to_db(Conn, User_id, Key) ->
    _pipe = Conn,
    _pipe@1 = db@session_key:add(_pipe, User_id, Key),
    gleam@result:map_error(
        _pipe@1,
        fun(E) ->
            {add_db_err, S} = E,
            {sign_up_failed, S}
        end
    ).

-spec sign_up(sqlight:connection(), binary(), binary()) -> {ok, binary()} |
    {error, sign_up_err()}.
sign_up(Conn, Username, Password) ->
    gleam@bool:guard(
        begin
            _pipe = Username,
            gleam@string:length(_pipe)
        end
        < 5,
        {error, username_too_short},
        fun() ->
            gleam@bool:guard(
                begin
                    _pipe@1 = Password,
                    gleam@string:length(_pipe@1)
                end
                < 5,
                {error, password_too_short},
                fun() ->
                    gleam@result:'try'(
                        begin
                            _pipe@2 = Conn,
                            add_user_to_db(_pipe@2, Username, Password)
                        end,
                        fun(_use0) ->
                            nil = _use0,
                            gleam@result:'try'(
                                begin
                                    _pipe@3 = Conn,
                                    get_user_from_db(_pipe@3, Username)
                                end,
                                fun(User) ->
                                    Key = users@session_key:generate(),
                                    gleam@result:'try'(
                                        begin
                                            _pipe@4 = Conn,
                                            add_session_key_to_db(
                                                _pipe@4,
                                                erlang:element(2, User),
                                                Key
                                            )
                                        end,
                                        fun(_use0@1) ->
                                            nil = _use0@1,
                                            _pipe@5 = Key,
                                            {ok, _pipe@5}
                                        end
                                    )
                                end
                            )
                        end
                    )
                end
            )
        end
    ).
