src/automata@rrule@normalize.erl

-module(automata@rrule@normalize).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/automata/rrule/normalize.gleam").
-export([normalize/2]).
-export_type([normalize_error/0, r_rule_plan/0]).

-type normalize_error() :: {invalid_anchor, automata@schedule@ast:date_time()}.

-type r_rule_plan() :: {r_rule_plan,
        automata@schedule@ast:date_time(),
        automata@rrule@validator:frequency(),
        integer(),
        automata@rrule@validator:end_condition(),
        gleam@option:option(list(automata@rrule@validator:weekday_specifier())),
        gleam@option:option(list(integer())),
        gleam@option:option(list(integer())),
        list(integer()),
        list(integer()),
        integer()}.

-file("src/automata/rrule/normalize.gleam", 53).
-spec default_by_day(
    automata@rrule@validator:valid_r_rule(),
    automata@schedule@ast:date_time()
) -> gleam@option:option(list(automata@rrule@validator:weekday_specifier())).
default_by_day(Spec, Anchor) ->
    case automata@rrule@validator:by_day(Spec) of
        {some, Values} ->
            {some, Values};

        none ->
            case automata@rrule@validator:frequency(Spec) of
                weekly ->
                    {some,
                        [{every_weekday,
                                automata@internal@calendar:weekday(Anchor)}]};

                _ ->
                    none
            end
    end.

-file("src/automata/rrule/normalize.gleam", 68).
-spec default_by_month(
    automata@rrule@validator:valid_r_rule(),
    automata@schedule@ast:date_time()
) -> gleam@option:option(list(integer())).
default_by_month(Spec, Anchor) ->
    case automata@rrule@validator:by_month(Spec) of
        {some, Values} ->
            {some, Values};

        none ->
            case automata@rrule@validator:frequency(Spec) of
                yearly ->
                    case {automata@rrule@validator:by_day(Spec),
                        automata@rrule@validator:by_month_day(Spec)} of
                        {none, none} ->
                            {some,
                                [erlang:element(3, erlang:element(2, Anchor))]};

                        {_, _} ->
                            none
                    end;

                _ ->
                    none
            end
    end.

-file("src/automata/rrule/normalize.gleam", 86).
-spec default_by_month_day(
    automata@rrule@validator:valid_r_rule(),
    automata@schedule@ast:date_time()
) -> gleam@option:option(list(integer())).
default_by_month_day(Spec, Anchor) ->
    case automata@rrule@validator:by_month_day(Spec) of
        {some, Values} ->
            {some, Values};

        none ->
            case automata@rrule@validator:by_day(Spec) of
                {some, _} ->
                    none;

                none ->
                    case automata@rrule@validator:frequency(Spec) of
                        monthly ->
                            {some,
                                [erlang:element(4, erlang:element(2, Anchor))]};

                        yearly ->
                            {some,
                                [erlang:element(4, erlang:element(2, Anchor))]};

                        _ ->
                            none
                    end
            end
    end.

-file("src/automata/rrule/normalize.gleam", 25).
-spec normalize(
    automata@rrule@validator:valid_r_rule(),
    automata@schedule@ast:date_time()
) -> {ok, r_rule_plan()} | {error, normalize_error()}.
normalize(Spec, Anchor) ->
    case automata@internal@calendar:is_valid_datetime(Anchor) of
        false ->
            {error, {invalid_anchor, Anchor}};

        true ->
            {ok,
                {r_rule_plan,
                    Anchor,
                    automata@rrule@validator:frequency(Spec),
                    automata@rrule@validator:interval(Spec),
                    automata@rrule@validator:end_condition(Spec),
                    default_by_day(Spec, Anchor),
                    default_by_month(Spec, Anchor),
                    default_by_month_day(Spec, Anchor),
                    case automata@rrule@validator:by_hour(Spec) of
                        {some, Values} ->
                            Values;

                        none ->
                            [erlang:element(2, erlang:element(3, Anchor))]
                    end,
                    case automata@rrule@validator:by_minute(Spec) of
                        {some, Values@1} ->
                            Values@1;

                        none ->
                            [erlang:element(3, erlang:element(3, Anchor))]
                    end,
                    erlang:element(4, erlang:element(3, Anchor))}}
    end.