defmodule Aprsme.DevicesSeederTest do
  use Aprsme.DataCase, async: false

  alias Aprsme.Devices
  alias Aprsme.DevicesSeeder
  alias Aprsme.Repo

  setup do
    Repo.delete_all(Devices)
    :ok
  end

  describe "seed_from_json/1" do
    test "seeds the devices table from the default test JSON file" do
      assert {:ok, :seeded} = DevicesSeeder.seed_from_json()
      assert Repo.aggregate(Devices, :count) > 0
    end

    test "returns an error tuple when the file does not exist" do
      assert {:error, message} = DevicesSeeder.seed_from_json("nonexistent/file.json")
      assert message =~ "Failed to read file"
    end

    test "returns an error tuple when the JSON is malformed" do
      tmp = Path.join(System.tmp_dir!(), "bad_devices_#{System.unique_integer([:positive])}.json")
      File.write!(tmp, "{malformed json")

      try do
        assert {:error, message} = DevicesSeeder.seed_from_json(tmp)
        assert message =~ "Failed to decode JSON"
      after
        File.rm(tmp)
      end
    end

    test "wipes existing devices before seeding" do
      Repo.insert!(%Devices{identifier: "TOWIPE", vendor: "v", model: "m"})
      assert {:ok, :seeded} = DevicesSeeder.seed_from_json()
      assert Repo.get_by(Devices, identifier: "TOWIPE") == nil
    end

    test "wraps a non-list features value into a single-element list" do
      tmp = Path.join(System.tmp_dir!(), "single_feature_#{System.unique_integer([:positive])}.json")

      File.write!(
        tmp,
        Jason.encode!(%{
          "tocalls" => %{
            "APSGL" => %{"vendor" => "V", "model" => "M", "features" => "single-feature"}
          }
        })
      )

      try do
        assert {:ok, :seeded} = DevicesSeeder.seed_from_json(tmp)
        dev = Repo.get_by(Devices, identifier: "APSGL")
        assert dev.features == ["single-feature"]
      after
        File.rm(tmp)
      end
    end

    test "preserves a list-typed features value as-is" do
      tmp = Path.join(System.tmp_dir!(), "list_feature_#{System.unique_integer([:positive])}.json")

      File.write!(
        tmp,
        Jason.encode!(%{
          "tocalls" => %{
            "APLST" => %{"vendor" => "V", "model" => "M", "features" => ["a", "b"]}
          }
        })
      )

      try do
        assert {:ok, :seeded} = DevicesSeeder.seed_from_json(tmp)
        dev = Repo.get_by(Devices, identifier: "APLST")
        assert dev.features == ["a", "b"]
      after
        File.rm(tmp)
      end
    end
  end
end
