defmodule Aprsme.CleanupSchedulerTest do
  # Mutates :aprsme, :cleanup_scheduler env; must be serialized with anything
  # else that reads it.
  use ExUnit.Case, async: false

  alias Aprsme.CleanupScheduler

  setup do
    original = Application.get_env(:aprsme, :cleanup_scheduler)
    on_exit(fn -> Application.put_env(:aprsme, :cleanup_scheduler, original || []) end)
    :ok
  end

  describe "init/1" do
    test "returns default 6-hour interval when enabled" do
      Application.put_env(:aprsme, :cleanup_scheduler, enabled: true)
      assert {:ok, %{interval: interval}} = CleanupScheduler.init([])
      assert interval == 6 * 60 * 60 * 1000
    end

    test "honors a configured interval" do
      Application.put_env(:aprsme, :cleanup_scheduler, enabled: true, interval: 5_000)
      assert {:ok, %{interval: 5_000}} = CleanupScheduler.init([])
    end

    test "returns nil interval when disabled" do
      Application.put_env(:aprsme, :cleanup_scheduler, enabled: false)
      assert {:ok, %{interval: nil}} = CleanupScheduler.init([])
    end

    test "defaults to enabled when no config" do
      Application.put_env(:aprsme, :cleanup_scheduler, [])
      assert {:ok, %{interval: interval}} = CleanupScheduler.init([])
      assert is_integer(interval)
    end

    test "init schedules a follow-up :schedule_cleanup message when enabled" do
      Application.put_env(:aprsme, :cleanup_scheduler, enabled: true, interval: 10)
      {:ok, _state} = CleanupScheduler.init([])
      # Process.send_after targets self() (the test process in this call context),
      # so we should receive the scheduled message shortly.
      assert_receive :schedule_cleanup, 1000
    end
  end

  describe "handle_info/2" do
    test "no-op for :schedule_cleanup when disabled" do
      state = %{interval: nil}
      assert CleanupScheduler.handle_info(:schedule_cleanup, state) == {:noreply, state}
    end

    test "runs cleanup and reschedules when interval is an integer" do
      state = %{interval: 100}

      assert {:noreply, ^state} = CleanupScheduler.handle_info(:schedule_cleanup, state)
      # Next cleanup scheduled.
      assert_receive :schedule_cleanup, 1000
    end
  end
end
