defmodule Towerops.Monitoring.MonitoringCheckTest do
  use Towerops.DataCase

  import Towerops.AccountsFixtures
  import Towerops.OrganizationsFixtures

  alias Towerops.Agents
  alias Towerops.Monitoring
  alias Towerops.Monitoring.MonitoringCheck
  alias Towerops.Sites

  describe "MonitoringCheck schema" do
    test "valid changeset with required fields" do
      {device, _agent} = create_device_with_agent()

      changeset =
        MonitoringCheck.changeset(%MonitoringCheck{}, %{
          device_id: device.id,
          status: "success",
          checked_at: DateTime.utc_now()
        })

      assert changeset.valid?
    end

    test "invalid changeset missing required fields" do
      changeset = MonitoringCheck.changeset(%MonitoringCheck{}, %{})

      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).device_id
      assert "can't be blank" in errors_on(changeset).status
      assert "can't be blank" in errors_on(changeset).checked_at
    end

    test "valid changeset with all fields" do
      {device, agent} = create_device_with_agent()

      changeset =
        MonitoringCheck.changeset(%MonitoringCheck{}, %{
          device_id: device.id,
          agent_token_id: agent.id,
          status: "success",
          response_time_ms: 42.5,
          checked_at: DateTime.utc_now()
        })

      assert changeset.valid?
    end
  end

  describe "Monitoring.create_monitoring_check/1" do
    test "inserts a monitoring check record" do
      {device, agent} = create_device_with_agent()
      now = DateTime.truncate(DateTime.utc_now(), :second)

      assert {:ok, check} =
               Monitoring.create_monitoring_check(%{
                 device_id: device.id,
                 agent_token_id: agent.id,
                 status: "success",
                 response_time_ms: 12.5,
                 checked_at: now
               })

      assert check.device_id == device.id
      assert check.agent_token_id == agent.id
      assert check.status == "success"
      assert check.response_time_ms == 12.5
      assert check.checked_at == now
    end

    test "inserts without agent_token_id" do
      {device, _agent} = create_device_with_agent()
      now = DateTime.truncate(DateTime.utc_now(), :second)

      assert {:ok, check} =
               Monitoring.create_monitoring_check(%{
                 device_id: device.id,
                 status: "failure",
                 checked_at: now
               })

      assert check.device_id == device.id
      assert is_nil(check.agent_token_id)
      assert check.status == "failure"
      assert is_nil(check.response_time_ms)
    end

    test "rejects invalid attrs" do
      assert {:error, changeset} = Monitoring.create_monitoring_check(%{})
      refute changeset.valid?
    end
  end

  defp create_device_with_agent do
    user = user_fixture()
    org = organization_fixture(user.id)
    {:ok, agent, _token} = Agents.create_agent_token(org.id, "Test Agent")
    {:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: org.id})

    {:ok, device} =
      Towerops.Devices.create_device(%{
        name: "Test Router",
        ip_address: "192.168.1.1",
        site_id: site.id,
        organization_id: org.id,
        snmp_enabled: true,
        snmp_community: "public",
        snmp_version: "2c"
      })

    {device, agent}
  end
end
