defmodule Towerops.Workers.JobHealthCheckWorkerTest do
  use Towerops.DataCase

  import Ecto.Query

  alias Towerops.DevicesFixtures
  alias Towerops.Repo
  alias Towerops.Workers.JobHealthCheckWorker

  describe "perform/1" do
    test "recovers missing monitor jobs" do
      device = DevicesFixtures.device_fixture(%{monitoring_enabled: true})

      # Ensure no jobs exist initially
      Repo.delete_all(Oban.Job)

      assert :ok = JobHealthCheckWorker.perform(%Oban.Job{})

      # Verify job was created
      assert Repo.one(
               from j in Oban.Job,
                 where:
                   j.worker == "Towerops.Workers.DeviceMonitorWorker" and fragment("args->>'device_id' = ?", ^device.id)
             )
    end

    @tag :skip
    test "recovers missing poller jobs (DEPRECATED: per-check jobs now)" do
      # This test is deprecated - SNMP polling is now handled by per-check
      # CheckExecutorWorker jobs, not device-level DevicePollerWorker jobs
    end

    test "does not create duplicate jobs if they already exist" do
      _device = DevicesFixtures.device_fixture(%{monitoring_enabled: true, snmp_enabled: true})

      # Only DeviceMonitorWorker job is created (SNMP polling via per-check jobs now)

      initial_job_count = Repo.aggregate(Oban.Job, :count)
      assert initial_job_count == 1

      assert :ok = JobHealthCheckWorker.perform(%Oban.Job{})

      final_job_count = Repo.aggregate(Oban.Job, :count)
      assert final_job_count == initial_job_count
    end

    test "handles mixed scenario correctly" do
      # Device 1: Monitoring enabled (should have 1 job - DeviceMonitorWorker)
      device1 = DevicesFixtures.device_fixture(%{monitoring_enabled: true, snmp_enabled: false})

      # Device 2: SNMP enabled (should have 0 device-level jobs - checks have their own jobs)
      _device2 = DevicesFixtures.device_fixture(%{monitoring_enabled: false, snmp_enabled: true})

      # Device 3: Both enabled (should have 1 job - DeviceMonitorWorker only)
      _device3 = DevicesFixtures.device_fixture(%{monitoring_enabled: true, snmp_enabled: true})

      # Simulate missing job for device 1 by deleting it
      Repo.delete_all(from j in Oban.Job, where: fragment("args->>'device_id' = ?", ^device1.id))

      # Ensure we only have jobs for device 3 left (1 job - DeviceMonitorWorker)
      assert Repo.aggregate(Oban.Job, :count) == 1

      assert :ok = JobHealthCheckWorker.perform(%Oban.Job{})

      # Verify job created for device 1
      assert Repo.one(
               from j in Oban.Job,
                 where:
                   j.worker == "Towerops.Workers.DeviceMonitorWorker" and fragment("args->>'device_id' = ?", ^device1.id)
             )

      # Device 2 has no device-level jobs (SNMP polling via per-check jobs)
      # Total jobs should be 2 (1 existing for device3 + 1 new for device1)
      assert Repo.aggregate(Oban.Job, :count) == 2
    end
  end
end
