defmodule Oban.Pro.Stages.Rate do
  @moduledoc false

  @behaviour Oban.Pro.Stage

  alias Oban.Validation

  defstruct [:weight]

  @impl Oban.Pro.Stage
  def init(_worker, opts) when is_list(opts) do
    with :ok <- validate(opts) do
      {:ok, struct(__MODULE__, opts)}
    end
  end

  @impl Oban.Pro.Stage
  def before_new(args, opts, conf) do
    {rate_opts, opts} = Keyword.pop(opts, :rate, [])

    weight = Keyword.get(rate_opts, :weight, conf.weight)

    if is_integer(weight) do
      meta = %{"rate_weight" => weight}
      opts = Keyword.update(opts, :meta, meta, &Map.merge(&1, meta))

      {:ok, args, opts}
    else
      {:ok, args, opts}
    end
  end

  defp validate(opts) do
    Validation.validate_schema(opts, weight: :pos_integer)
  end
end
