defmodule Aprsme.ReleaseTest do
  # Mutates DEPLOYED_AT env var and :aprsme, :deployed_at — can't run in parallel.
  use ExUnit.Case, async: false

  alias Aprsme.Release

  setup do
    original_env = System.get_env("DEPLOYED_AT")
    original_config = Application.get_env(:aprsme, :deployed_at)

    on_exit(fn ->
      if is_nil(original_env) do
        System.delete_env("DEPLOYED_AT")
      else
        System.put_env("DEPLOYED_AT", original_env)
      end

      Application.put_env(:aprsme, :deployed_at, original_config)
    end)

    :ok
  end

  describe "init/0" do
    test "returns DateTime and stores it in app env when DEPLOYED_AT is unset" do
      System.delete_env("DEPLOYED_AT")
      Application.delete_env(:aprsme, :deployed_at)

      result = Release.init()
      assert %DateTime{} = result
      assert Application.get_env(:aprsme, :deployed_at) == result
    end

    test "parses valid ISO8601 DEPLOYED_AT" do
      System.put_env("DEPLOYED_AT", "2024-01-15T12:00:00Z")
      result = Release.init()
      assert DateTime.to_iso8601(result) == "2024-01-15T12:00:00Z"
    end

    test "falls back to current time for invalid DEPLOYED_AT" do
      System.put_env("DEPLOYED_AT", "not-a-timestamp")
      before = DateTime.utc_now()
      result = Release.init()
      assert %DateTime{} = result
      assert DateTime.compare(result, before) in [:gt, :eq]
    end
  end

  describe "deployed_at/0" do
    test "returns the stored value when set" do
      dt = ~U[2024-06-01 00:00:00Z]
      Application.put_env(:aprsme, :deployed_at, dt)
      assert Release.deployed_at() == dt
    end

    test "initializes to current time when unset" do
      Application.delete_env(:aprsme, :deployed_at)
      result = Release.deployed_at()
      assert %DateTime{} = result
      assert Application.get_env(:aprsme, :deployed_at) == result
    end
  end
end
