src/lightspeed@ops@supervision.erl

-module(lightspeed@ops@supervision).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/ops/supervision.gleam").
-export([default_plan/1, validate/1, strategy_label/1, restart_label/1, child_ids/1]).
-export_type([restart/0, strategy/0, child_spec/0, plan/0, plan_error/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(" Supervision tree guidance for production Lightspeed deployments.\n").

-type restart() :: permanent | transient | temporary.

-type strategy() :: one_for_one | rest_for_one | one_for_all.

-type child_spec() :: {child_spec, binary(), binary(), restart(), integer()}.

-type plan() :: {plan, binary(), strategy(), list(child_spec())}.

-type plan_error() :: {missing_required_child, binary()} |
    {duplicate_child_id, binary()}.

-file("src/lightspeed/ops/supervision.gleam", 36).
?DOC(" Build a default plan with recommended Phase 7 children.\n").
-spec default_plan(binary()) -> plan().
default_plan(App_name) ->
    {plan,
        <<App_name/binary, "_supervisor"/utf8>>,
        one_for_one,
        [{child_spec,
                <<"session_registry"/utf8>>,
                <<"lightspeed.session_registry"/utf8>>,
                permanent,
                5000},
            {child_spec,
                <<"session_supervisor"/utf8>>,
                <<"lightspeed.session_supervisor"/utf8>>,
                permanent,
                5000},
            {child_spec,
                <<"transport_endpoint"/utf8>>,
                <<"lightspeed.transport_endpoint"/utf8>>,
                permanent,
                5000},
            {child_spec,
                <<"metrics_reporter"/utf8>>,
                <<"lightspeed.metrics_reporter"/utf8>>,
                transient,
                3000}]}.

-file("src/lightspeed/ops/supervision.gleam", 141).
-spec has_required(list(child_spec()), binary()) -> boolean().
has_required(Children, Required_id) ->
    case Children of
        [] ->
            false;

        [Child | Rest] ->
            case erlang:element(2, Child) =:= Required_id of
                true ->
                    true;

                false ->
                    has_required(Rest, Required_id)
            end
    end.

-file("src/lightspeed/ops/supervision.gleam", 152).
-spec missing_required(list(child_spec())) -> {ok, nil} | {error, plan_error()}.
missing_required(Children) ->
    case has_required(Children, <<"session_registry"/utf8>>) of
        false ->
            {error, {missing_required_child, <<"session_registry"/utf8>>}};

        true ->
            case has_required(Children, <<"session_supervisor"/utf8>>) of
                false ->
                    {error,
                        {missing_required_child, <<"session_supervisor"/utf8>>}};

                true ->
                    case has_required(Children, <<"transport_endpoint"/utf8>>) of
                        false ->
                            {error,
                                {missing_required_child,
                                    <<"transport_endpoint"/utf8>>}};

                        true ->
                            case has_required(
                                Children,
                                <<"metrics_reporter"/utf8>>
                            ) of
                                false ->
                                    {error,
                                        {missing_required_child,
                                            <<"metrics_reporter"/utf8>>}};

                                true ->
                                    {ok, nil}
                            end
                    end
            end
    end.

-file("src/lightspeed/ops/supervision.gleam", 130).
-spec contains_id(list(binary()), binary()) -> boolean().
contains_id(Ids, Target) ->
    case Ids of
        [] ->
            false;

        [Id | Rest] ->
            case Id =:= Target of
                true ->
                    true;

                false ->
                    contains_id(Rest, Target)
            end
    end.

-file("src/lightspeed/ops/supervision.gleam", 116).
-spec duplicate_id(list(child_spec()), list(binary())) -> {ok, nil} |
    {error, plan_error()}.
duplicate_id(Children, Seen_ids) ->
    case Children of
        [] ->
            {ok, nil};

        [Child | Rest] ->
            case contains_id(Seen_ids, erlang:element(2, Child)) of
                true ->
                    {error, {duplicate_child_id, erlang:element(2, Child)}};

                false ->
                    duplicate_id(Rest, [erlang:element(2, Child) | Seen_ids])
            end
    end.

-file("src/lightspeed/ops/supervision.gleam", 66).
?DOC(" Validate required child coverage and duplicate ids.\n").
-spec validate(plan()) -> {ok, nil} | {error, plan_error()}.
validate(Plan) ->
    case duplicate_id(erlang:element(4, Plan), []) of
        {ok, nil} ->
            case ((has_required(
                erlang:element(4, Plan),
                <<"session_registry"/utf8>>
            )
            andalso has_required(
                erlang:element(4, Plan),
                <<"session_supervisor"/utf8>>
            ))
            andalso has_required(
                erlang:element(4, Plan),
                <<"transport_endpoint"/utf8>>
            ))
            andalso has_required(
                erlang:element(4, Plan),
                <<"metrics_reporter"/utf8>>
            ) of
                true ->
                    {ok, nil};

                false ->
                    missing_required(erlang:element(4, Plan))
            end;

        {error, Error} ->
            {error, Error}
    end.

-file("src/lightspeed/ops/supervision.gleam", 84).
?DOC(" Stable plan label.\n").
-spec strategy_label(strategy()) -> binary().
strategy_label(Strategy) ->
    case Strategy of
        one_for_one ->
            <<"one_for_one"/utf8>>;

        rest_for_one ->
            <<"rest_for_one"/utf8>>;

        one_for_all ->
            <<"one_for_all"/utf8>>
    end.

-file("src/lightspeed/ops/supervision.gleam", 93).
?DOC(" Stable restart label.\n").
-spec restart_label(restart()) -> binary().
restart_label(Restart) ->
    case Restart of
        permanent ->
            <<"permanent"/utf8>>;

        transient ->
            <<"transient"/utf8>>;

        temporary ->
            <<"temporary"/utf8>>
    end.

-file("src/lightspeed/ops/supervision.gleam", 106).
-spec child_ids_loop(list(child_spec()), list(binary())) -> list(binary()).
child_ids_loop(Children, Ids_rev) ->
    case Children of
        [] ->
            lists:reverse(Ids_rev);

        [Child | Rest] ->
            child_ids_loop(Rest, [erlang:element(2, Child) | Ids_rev])
    end.

-file("src/lightspeed/ops/supervision.gleam", 102).
?DOC(" Child ids in declaration order.\n").
-spec child_ids(plan()) -> list(binary()).
child_ids(Plan) ->
    child_ids_loop(erlang:element(4, Plan), []).