src/automata@cron@evaluator.erl

-module(automata@cron@evaluator).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/automata/cron/evaluator.gleam").
-export([int_set_contains/2, first_value/1, next_value_at_or_after/2, matches/2]).

-file("src/automata/cron/evaluator.gleam", 22).
-spec int_set_contains(automata@cron@normalize:int_set(), integer()) -> boolean().
int_set_contains(Int_set, Value) ->
    case Int_set of
        {any_value, Min, Max} ->
            (Value >= Min) andalso (Value =< Max);

        {values, Values} ->
            gleam@list:any(Values, fun(Item) -> Item =:= Value end)
    end.

-file("src/automata/cron/evaluator.gleam", 29).
-spec first_value(automata@cron@normalize:int_set()) -> integer().
first_value(Int_set) ->
    case Int_set of
        {any_value, Min, _} ->
            Min;

        {values, [First | _]} ->
            First;

        {values, []} ->
            0
    end.

-file("src/automata/cron/evaluator.gleam", 52).
-spec next_list_value(list(integer()), integer()) -> gleam@option:option(integer()).
next_list_value(Values, Current) ->
    case Values of
        [] ->
            none;

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

                false ->
                    next_list_value(Rest, Current)
            end
    end.

-file("src/automata/cron/evaluator.gleam", 37).
-spec next_value_at_or_after(automata@cron@normalize:int_set(), integer()) -> gleam@option:option(integer()).
next_value_at_or_after(Int_set, Current) ->
    case Int_set of
        {any_value, Min, Max} ->
            case Current < Min of
                true ->
                    {some, Min};

                false ->
                    case Current > Max of
                        true ->
                            none;

                        false ->
                            {some, Current}
                    end
            end;

        {values, Values} ->
            next_list_value(Values, Current)
    end.

-file("src/automata/cron/evaluator.gleam", 79).
-spec is_any(automata@cron@normalize:int_set()) -> boolean().
is_any(Int_set) ->
    case Int_set of
        {any_value, _, _} ->
            true;

        {values, _} ->
            false
    end.

-file("src/automata/cron/evaluator.gleam", 63).
-spec matches_day(automata@cron@normalize:cron_plan(), boolean(), boolean()) -> boolean().
matches_day(Plan, Day_of_month_match, Day_of_week_match) ->
    Dom_any = is_any(erlang:element(4, Plan)),
    Dow_any = is_any(erlang:element(6, Plan)),
    case {Dom_any, Dow_any} of
        {true, true} ->
            true;

        {true, false} ->
            Day_of_week_match;

        {false, true} ->
            Day_of_month_match;

        {false, false} ->
            Day_of_month_match orelse Day_of_week_match
    end.

-file("src/automata/cron/evaluator.gleam", 7).
-spec matches(
    automata@cron@normalize:cron_plan(),
    automata@schedule@ast:date_time()
) -> boolean().
matches(Plan, At) ->
    Minute_match = int_set_contains(
        erlang:element(2, Plan),
        erlang:element(3, erlang:element(3, At))
    ),
    Hour_match = int_set_contains(
        erlang:element(3, Plan),
        erlang:element(2, erlang:element(3, At))
    ),
    Month_match = int_set_contains(
        erlang:element(5, Plan),
        erlang:element(3, erlang:element(2, At))
    ),
    Day_of_month_match = int_set_contains(
        erlang:element(4, Plan),
        erlang:element(4, erlang:element(2, At))
    ),
    Day_of_week_match = int_set_contains(
        erlang:element(6, Plan),
        automata@internal@calendar:day_of_week_number(At)
    ),
    (((Minute_match andalso Hour_match) andalso Month_match) andalso matches_day(
        Plan,
        Day_of_month_match,
        Day_of_week_match
    ))
    andalso (erlang:element(4, erlang:element(3, At)) =:= 0).