Skip to main content

lib/rulestead/admin/lifecycle_defaults.ex

defmodule Rulestead.Admin.LifecycleDefaults do
  @moduledoc false

  @expiring_types [:release, :experiment, :migration]
  @permanent_types [:kill_switch, :operational, :permission]

  @spec suggest(atom() | String.t(), keyword()) :: map()
  def suggest(flag_type, opts \\ []) do
    authored_mode = Keyword.get(opts, :authored_mode)
    authored_review_by = Keyword.get(opts, :authored_review_by)

    base =
      case normalize_flag_type(flag_type) do
        type when type in @expiring_types ->
          %{
            mode: :expiring,
            rationale: "#{humanize(type)} flags usually need an explicit sunset review.",
            default_source: :flag_type
          }

        type when type in @permanent_types ->
          %{
            mode: :permanent,
            rationale: "#{humanize(type)} flags are usually long-lived operational controls.",
            default_source: :flag_type
          }

        :remote_config ->
          %{
            mode: nil,
            rationale:
              "Remote config needs an explicit operator choice because usage can be temporary or durable.",
            default_source: :operator_required
          }

        _other ->
          %{
            mode: nil,
            rationale: "Choose an explicit lifecycle posture for this flag.",
            default_source: :operator_required
          }
      end

    base
    |> Map.put(:review_by, authored_review_by)
    |> Map.put(:default_overridden, not is_nil(authored_mode) and authored_mode != base.mode)
  end

  defp normalize_flag_type(value) when is_binary(value) do
    case String.trim(value) do
      "" ->
        nil

      normalized ->
        try do
          String.to_existing_atom(normalized)
        rescue
          ArgumentError -> nil
        end
    end
  end

  defp normalize_flag_type(value) when is_atom(value), do: value
  defp normalize_flag_type(_value), do: nil

  defp humanize(value) do
    value
    |> to_string()
    |> String.replace("_", " ")
  end
end