defmodule Towerops.Profiles.SensorOidTest do
  use Towerops.DataCase, async: true

  alias Towerops.Profiles
  alias Towerops.Profiles.SensorOid

  describe "changeset/2" do
    setup do
      {:ok, profile} = Profiles.create_profile(%{name: "Test Profile", vendor: "Test"})
      %{profile: profile}
    end

    test "valid changeset with all fields", %{profile: profile} do
      attrs = %{
        sensor_type: "temperature",
        mib_name: "TEST-MIB::temperature.0",
        sensor_descr: "CPU Temperature",
        sensor_unit: "celsius",
        sensor_divisor: 10,
        profile_id: profile.id
      }

      changeset = SensorOid.changeset(%SensorOid{}, attrs)
      assert changeset.valid?
    end

    test "valid changeset with minimal required fields", %{profile: profile} do
      attrs = %{
        sensor_type: "voltage",
        mib_name: "TEST-MIB::voltage.0",
        profile_id: profile.id
      }

      changeset = SensorOid.changeset(%SensorOid{}, attrs)
      assert changeset.valid?
      assert get_field(changeset, :sensor_divisor) == 1
    end

    test "invalid changeset without sensor_type", %{profile: profile} do
      attrs = %{
        mib_name: "TEST-MIB::temperature.0",
        profile_id: profile.id
      }

      changeset = SensorOid.changeset(%SensorOid{}, attrs)
      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).sensor_type
    end

    test "invalid changeset without mib_name", %{profile: profile} do
      attrs = %{
        sensor_type: "temperature",
        profile_id: profile.id
      }

      changeset = SensorOid.changeset(%SensorOid{}, attrs)
      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).mib_name
    end

    test "invalid changeset without profile_id" do
      attrs = %{
        sensor_type: "temperature",
        mib_name: "TEST-MIB::temperature.0"
      }

      changeset = SensorOid.changeset(%SensorOid{}, attrs)
      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).profile_id
    end

    test "valid changeset with various sensor types", %{profile: profile} do
      sensor_types = [
        "temperature",
        "voltage",
        "current",
        "power",
        "fanspeed",
        "humidity",
        "pressure"
      ]

      for sensor_type <- sensor_types do
        attrs = %{
          sensor_type: sensor_type,
          mib_name: "TEST-MIB::#{sensor_type}.0",
          profile_id: profile.id
        }

        changeset = SensorOid.changeset(%SensorOid{}, attrs)
        assert changeset.valid?
      end
    end

    test "valid changeset with various sensor units", %{profile: profile} do
      units = [
        {"temperature", "celsius"},
        {"temperature", "fahrenheit"},
        {"voltage", "volts"},
        {"current", "amperes"},
        {"power", "watts"},
        {"fanspeed", "rpm"}
      ]

      for {sensor_type, unit} <- units do
        attrs = %{
          sensor_type: sensor_type,
          mib_name: "TEST-MIB::test.0",
          sensor_unit: unit,
          profile_id: profile.id
        }

        changeset = SensorOid.changeset(%SensorOid{}, attrs)
        assert changeset.valid?
      end
    end

    test "valid changeset with various divisors", %{profile: profile} do
      divisors = [1, 10, 100, 1000]

      for divisor <- divisors do
        attrs = %{
          sensor_type: "temperature",
          mib_name: "TEST-MIB::temp.0",
          sensor_divisor: divisor,
          profile_id: profile.id
        }

        changeset = SensorOid.changeset(%SensorOid{}, attrs)
        assert changeset.valid?
        assert get_field(changeset, :sensor_divisor) == divisor
      end
    end

    test "valid changeset with nil optional fields", %{profile: profile} do
      attrs = %{
        sensor_type: "temperature",
        mib_name: "TEST-MIB::temp.0",
        sensor_descr: nil,
        sensor_unit: nil,
        profile_id: profile.id
      }

      changeset = SensorOid.changeset(%SensorOid{}, attrs)
      assert changeset.valid?
    end

    test "valid changeset with sensor description", %{profile: profile} do
      attrs = %{
        sensor_type: "temperature",
        mib_name: "TEST-MIB::temp.0",
        sensor_descr: "Board Temperature Sensor #1",
        profile_id: profile.id
      }

      changeset = SensorOid.changeset(%SensorOid{}, attrs)
      assert changeset.valid?
      assert get_field(changeset, :sensor_descr) == "Board Temperature Sensor #1"
    end
  end
end
