src/lightspeed@framework@http.erl

-module(lightspeed@framework@http).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/framework/http.gleam").
-export([request/9, from_request/1, request_path/1, request_method/1, request_body/1, request_session_id/1, request_csrf_token/1, request_origin/1, request_header/2, set_status/2, set_body/2, put_header/3, send/4, halt/1, halted/1, put_session/3, drop_session/2, session/2, session_all/1, put_flash/3, flash/2, clear_flash/1, flash_all/1, with_route_params/2, route_param/2, route_params/1, to_response/1, response_status/1, response_headers/1, response_body/1, response_session/1, response_flash/1, method_label/1, response_label/1]).
-export_type([method/0, request/0, route_param/0, response/0, conn/0]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(" Core HTTP connection model for framework-compatible endpoint flows.\n").

-type method() :: get |
    post |
    put |
    patch |
    delete |
    head |
    options |
    {other, binary()}.

-type request() :: {request,
        method(),
        binary(),
        list({binary(), binary()}),
        binary(),
        binary(),
        binary(),
        binary(),
        list({binary(), binary()}),
        list({binary(), binary()})}.

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

-type response() :: {response,
        integer(),
        list({binary(), binary()}),
        binary(),
        list({binary(), binary()}),
        list({binary(), binary()})}.

-type conn() :: {conn, request(), response(), boolean(), list(route_param())}.

-file("src/lightspeed/framework/http.gleam", 61).
?DOC(" Build a request.\n").
-spec request(
    method(),
    binary(),
    list({binary(), binary()}),
    binary(),
    binary(),
    binary(),
    binary(),
    list({binary(), binary()}),
    list({binary(), binary()})
) -> request().
request(
    Method,
    Path,
    Headers,
    Body,
    Session_id,
    Csrf_token,
    Origin,
    Session,
    Flash
) ->
    {request,
        Method,
        Path,
        Headers,
        Body,
        Session_id,
        Csrf_token,
        Origin,
        Session,
        Flash}.

-file("src/lightspeed/framework/http.gleam", 86).
?DOC(" Create a new connection from one request.\n").
-spec from_request(request()) -> conn().
from_request(Request) ->
    {conn,
        Request,
        {response,
            200,
            [],
            <<""/utf8>>,
            erlang:element(9, Request),
            erlang:element(10, Request)},
        false,
        []}.

-file("src/lightspeed/framework/http.gleam", 102).
?DOC(" Request path.\n").
-spec request_path(conn()) -> binary().
request_path(Conn) ->
    erlang:element(3, erlang:element(2, Conn)).

-file("src/lightspeed/framework/http.gleam", 107).
?DOC(" Request method.\n").
-spec request_method(conn()) -> method().
request_method(Conn) ->
    erlang:element(2, erlang:element(2, Conn)).

-file("src/lightspeed/framework/http.gleam", 112).
?DOC(" Request body.\n").
-spec request_body(conn()) -> binary().
request_body(Conn) ->
    erlang:element(5, erlang:element(2, Conn)).

-file("src/lightspeed/framework/http.gleam", 117).
?DOC(" Request session id.\n").
-spec request_session_id(conn()) -> binary().
request_session_id(Conn) ->
    erlang:element(6, erlang:element(2, Conn)).

-file("src/lightspeed/framework/http.gleam", 122).
?DOC(" Request CSRF token.\n").
-spec request_csrf_token(conn()) -> binary().
request_csrf_token(Conn) ->
    erlang:element(7, erlang:element(2, Conn)).

-file("src/lightspeed/framework/http.gleam", 127).
?DOC(" Request origin.\n").
-spec request_origin(conn()) -> binary().
request_origin(Conn) ->
    erlang:element(8, erlang:element(2, Conn)).

-file("src/lightspeed/framework/http.gleam", 296).
-spec normalize_header(binary()) -> binary().
normalize_header(Key) ->
    string:lowercase(Key).

-file("src/lightspeed/framework/http.gleam", 300).
-spec find_header(list({binary(), binary()}), binary()) -> gleam@option:option(binary()).
find_header(Headers, Key) ->
    case Headers of
        [] ->
            none;

        [{Entry_key, Value} | Rest] ->
            case normalize_header(Entry_key) =:= Key of
                true ->
                    {some, Value};

                false ->
                    find_header(Rest, Key)
            end
    end.

-file("src/lightspeed/framework/http.gleam", 132).
?DOC(" Request header by key.\n").
-spec request_header(conn(), binary()) -> gleam@option:option(binary()).
request_header(Conn, Key) ->
    find_header(
        erlang:element(4, erlang:element(2, Conn)),
        normalize_header(Key)
    ).

-file("src/lightspeed/framework/http.gleam", 137).
?DOC(" Set one response status.\n").
-spec set_status(conn(), integer()) -> conn().
set_status(Conn, Status) ->
    Response = erlang:element(3, Conn),
    {conn,
        erlang:element(2, Conn),
        {response,
            Status,
            erlang:element(3, Response),
            erlang:element(4, Response),
            erlang:element(5, Response),
            erlang:element(6, Response)},
        erlang:element(4, Conn),
        erlang:element(5, Conn)}.

-file("src/lightspeed/framework/http.gleam", 143).
?DOC(" Set one response body.\n").
-spec set_body(conn(), binary()) -> conn().
set_body(Conn, Body) ->
    Response = erlang:element(3, Conn),
    {conn,
        erlang:element(2, Conn),
        {response,
            erlang:element(2, Response),
            erlang:element(3, Response),
            Body,
            erlang:element(5, Response),
            erlang:element(6, Response)},
        erlang:element(4, Conn),
        erlang:element(5, Conn)}.

-file("src/lightspeed/framework/http.gleam", 314).
-spec upsert_header(list({binary(), binary()}), binary(), binary()) -> list({binary(),
    binary()}).
upsert_header(Headers, Key, Value) ->
    case Headers of
        [] ->
            [{Key, Value}];

        [{Entry_key, Entry_value} | Rest] ->
            case normalize_header(Entry_key) =:= Key of
                true ->
                    [{Key, Value} | Rest];

                false ->
                    [{Entry_key, Entry_value} | upsert_header(Rest, Key, Value)]
            end
    end.

-file("src/lightspeed/framework/http.gleam", 149).
?DOC(" Set or replace one response header.\n").
-spec put_header(conn(), binary(), binary()) -> conn().
put_header(Conn, Key, Value) ->
    Response = erlang:element(3, Conn),
    Normalized_key = normalize_header(Key),
    Updated_headers = upsert_header(
        erlang:element(3, Response),
        Normalized_key,
        Value
    ),
    {conn,
        erlang:element(2, Conn),
        {response,
            erlang:element(2, Response),
            Updated_headers,
            erlang:element(4, Response),
            erlang:element(5, Response),
            erlang:element(6, Response)},
        erlang:element(4, Conn),
        erlang:element(5, Conn)}.

-file("src/lightspeed/framework/http.gleam", 158).
?DOC(" Write a full response tuple.\n").
-spec send(conn(), integer(), binary(), binary()) -> conn().
send(Conn, Status, Content_type, Body) ->
    _pipe = Conn,
    _pipe@1 = set_status(_pipe, Status),
    _pipe@2 = put_header(_pipe@1, <<"content-type"/utf8>>, Content_type),
    set_body(_pipe@2, Body).

-file("src/lightspeed/framework/http.gleam", 171).
?DOC(" Halt further endpoint processing.\n").
-spec halt(conn()) -> conn().
halt(Conn) ->
    {conn,
        erlang:element(2, Conn),
        erlang:element(3, Conn),
        true,
        erlang:element(5, Conn)}.

-file("src/lightspeed/framework/http.gleam", 176).
?DOC(" True when the connection has been halted.\n").
-spec halted(conn()) -> boolean().
halted(Conn) ->
    erlang:element(4, Conn).

-file("src/lightspeed/framework/http.gleam", 340).
-spec upsert_pair(list({binary(), binary()}), binary(), binary()) -> list({binary(),
    binary()}).
upsert_pair(Entries, Key, Value) ->
    case Entries of
        [] ->
            [{Key, Value}];

        [{Entry_key, Entry_value} | Rest] ->
            case Entry_key =:= Key of
                true ->
                    [{Key, Value} | Rest];

                false ->
                    [{Entry_key, Entry_value} | upsert_pair(Rest, Key, Value)]
            end
    end.

-file("src/lightspeed/framework/http.gleam", 181).
?DOC(" Update session entry in response state.\n").
-spec put_session(conn(), binary(), binary()) -> conn().
put_session(Conn, Key, Value) ->
    Response = erlang:element(3, Conn),
    Session = upsert_pair(erlang:element(5, Response), Key, Value),
    {conn,
        erlang:element(2, Conn),
        {response,
            erlang:element(2, Response),
            erlang:element(3, Response),
            erlang:element(4, Response),
            Session,
            erlang:element(6, Response)},
        erlang:element(4, Conn),
        erlang:element(5, Conn)}.

-file("src/lightspeed/framework/http.gleam", 355).
-spec remove_pair(list({binary(), binary()}), binary()) -> list({binary(),
    binary()}).
remove_pair(Entries, Key) ->
    case Entries of
        [] ->
            [];

        [{Entry_key, Entry_value} | Rest] ->
            case Entry_key =:= Key of
                true ->
                    remove_pair(Rest, Key);

                false ->
                    [{Entry_key, Entry_value} | remove_pair(Rest, Key)]
            end
    end.

-file("src/lightspeed/framework/http.gleam", 188).
?DOC(" Delete session entry in response state.\n").
-spec drop_session(conn(), binary()) -> conn().
drop_session(Conn, Key) ->
    Response = erlang:element(3, Conn),
    Session = remove_pair(erlang:element(5, Response), Key),
    {conn,
        erlang:element(2, Conn),
        {response,
            erlang:element(2, Response),
            erlang:element(3, Response),
            erlang:element(4, Response),
            Session,
            erlang:element(6, Response)},
        erlang:element(4, Conn),
        erlang:element(5, Conn)}.

-file("src/lightspeed/framework/http.gleam", 329).
-spec find_pair(list({binary(), binary()}), binary()) -> gleam@option:option(binary()).
find_pair(Entries, Key) ->
    case Entries of
        [] ->
            none;

        [{Entry_key, Value} | Rest] ->
            case Entry_key =:= Key of
                true ->
                    {some, Value};

                false ->
                    find_pair(Rest, Key)
            end
    end.

-file("src/lightspeed/framework/http.gleam", 195).
?DOC(" Read session entry from response state.\n").
-spec session(conn(), binary()) -> gleam@option:option(binary()).
session(Conn, Key) ->
    find_pair(erlang:element(5, erlang:element(3, Conn)), Key).

-file("src/lightspeed/framework/http.gleam", 200).
?DOC(" Full response-session state.\n").
-spec session_all(conn()) -> list({binary(), binary()}).
session_all(Conn) ->
    erlang:element(5, erlang:element(3, Conn)).

-file("src/lightspeed/framework/http.gleam", 205).
?DOC(" Update flash entry in response state.\n").
-spec put_flash(conn(), binary(), binary()) -> conn().
put_flash(Conn, Key, Value) ->
    Response = erlang:element(3, Conn),
    Flash = upsert_pair(erlang:element(6, Response), Key, Value),
    {conn,
        erlang:element(2, Conn),
        {response,
            erlang:element(2, Response),
            erlang:element(3, Response),
            erlang:element(4, Response),
            erlang:element(5, Response),
            Flash},
        erlang:element(4, Conn),
        erlang:element(5, Conn)}.

-file("src/lightspeed/framework/http.gleam", 212).
?DOC(" Read flash entry from response state.\n").
-spec flash(conn(), binary()) -> gleam@option:option(binary()).
flash(Conn, Key) ->
    find_pair(erlang:element(6, erlang:element(3, Conn)), Key).

-file("src/lightspeed/framework/http.gleam", 217).
?DOC(" Clear all flash entries.\n").
-spec clear_flash(conn()) -> conn().
clear_flash(Conn) ->
    Response = erlang:element(3, Conn),
    {conn,
        erlang:element(2, Conn),
        {response,
            erlang:element(2, Response),
            erlang:element(3, Response),
            erlang:element(4, Response),
            erlang:element(5, Response),
            []},
        erlang:element(4, Conn),
        erlang:element(5, Conn)}.

-file("src/lightspeed/framework/http.gleam", 223).
?DOC(" Full response-flash state.\n").
-spec flash_all(conn()) -> list({binary(), binary()}).
flash_all(Conn) ->
    erlang:element(6, erlang:element(3, Conn)).

-file("src/lightspeed/framework/http.gleam", 228).
?DOC(" Set route params on the connection.\n").
-spec with_route_params(conn(), list(route_param())) -> conn().
with_route_params(Conn, Params) ->
    {conn,
        erlang:element(2, Conn),
        erlang:element(3, Conn),
        erlang:element(4, Conn),
        Params}.

-file("src/lightspeed/framework/http.gleam", 369).
-spec find_param(list(route_param()), binary()) -> gleam@option:option(binary()).
find_param(Params, Key) ->
    case Params of
        [] ->
            none;

        [{route_param, Name, Value} | Rest] ->
            case Name =:= Key of
                true ->
                    {some, Value};

                false ->
                    find_param(Rest, Key)
            end
    end.

-file("src/lightspeed/framework/http.gleam", 233).
?DOC(" Route param value by key.\n").
-spec route_param(conn(), binary()) -> gleam@option:option(binary()).
route_param(Conn, Key) ->
    find_param(erlang:element(5, Conn), Key).

-file("src/lightspeed/framework/http.gleam", 238).
?DOC(" All route params.\n").
-spec route_params(conn()) -> list(route_param()).
route_params(Conn) ->
    erlang:element(5, Conn).

-file("src/lightspeed/framework/http.gleam", 243).
?DOC(" Final response.\n").
-spec to_response(conn()) -> response().
to_response(Conn) ->
    erlang:element(3, Conn).

-file("src/lightspeed/framework/http.gleam", 248).
?DOC(" Response status code.\n").
-spec response_status(response()) -> integer().
response_status(Response) ->
    erlang:element(2, Response).

-file("src/lightspeed/framework/http.gleam", 253).
?DOC(" Response headers.\n").
-spec response_headers(response()) -> list({binary(), binary()}).
response_headers(Response) ->
    erlang:element(3, Response).

-file("src/lightspeed/framework/http.gleam", 258).
?DOC(" Response body.\n").
-spec response_body(response()) -> binary().
response_body(Response) ->
    erlang:element(4, Response).

-file("src/lightspeed/framework/http.gleam", 263).
?DOC(" Response session state.\n").
-spec response_session(response()) -> list({binary(), binary()}).
response_session(Response) ->
    erlang:element(5, Response).

-file("src/lightspeed/framework/http.gleam", 268).
?DOC(" Response flash state.\n").
-spec response_flash(response()) -> list({binary(), binary()}).
response_flash(Response) ->
    erlang:element(6, Response).

-file("src/lightspeed/framework/http.gleam", 273).
?DOC(" Stable method label.\n").
-spec method_label(method()) -> binary().
method_label(Method) ->
    case Method of
        get ->
            <<"GET"/utf8>>;

        post ->
            <<"POST"/utf8>>;

        put ->
            <<"PUT"/utf8>>;

        patch ->
            <<"PATCH"/utf8>>;

        delete ->
            <<"DELETE"/utf8>>;

        head ->
            <<"HEAD"/utf8>>;

        options ->
            <<"OPTIONS"/utf8>>;

        {other, Label} ->
            Label
    end.

-file("src/lightspeed/framework/http.gleam", 380).
-spec content_type_label(list({binary(), binary()})) -> binary().
content_type_label(Headers) ->
    case find_header(Headers, <<"content-type"/utf8>>) of
        {some, Value} ->
            Value;

        none ->
            <<"unset"/utf8>>
    end.

-file("src/lightspeed/framework/http.gleam", 287).
?DOC(" Stable response label for fixture assertions.\n").
-spec response_label(response()) -> binary().
response_label(Response) ->
    <<<<<<<<<<"status="/utf8,
                        (erlang:integer_to_binary(erlang:element(2, Response)))/binary>>/binary,
                    ",content_type="/utf8>>/binary,
                (content_type_label(erlang:element(3, Response)))/binary>>/binary,
            ",body_bytes="/utf8>>/binary,
        (erlang:integer_to_binary(string:length(erlang:element(4, Response))))/binary>>.