defmodule Towerops.Snmp.MibTranslatorTest do
  use ExUnit.Case, async: true

  alias Towerops.Snmp.MibTranslator

  # NOTE: Tests that depend on the NIF (ToweropsNative) are commented out
  # in this worktree because the NIF is stubbed. Re-enable when NIF is available.

  describe "translate/1" do
    test "returns numeric OID unchanged" do
      assert MibTranslator.translate("1.3.6.1.2.1.1.1.0") == {:ok, "1.3.6.1.2.1.1.1.0"}
    end

    test "returns numeric OID with leading dot unchanged" do
      assert MibTranslator.translate(".1.3.6.1.2.1.1.1.0") == {:ok, ".1.3.6.1.2.1.1.1.0"}
    end

    # Requires NIF
    # test "translates standard SNMPv2-MIB names" do
    #   assert {:ok, oid} = MibTranslator.translate("SNMPv2-MIB::sysDescr.0")
    #   assert oid == "1.3.6.1.2.1.1.1.0" or oid == ".1.3.6.1.2.1.1.1.0"
    # end

    test "returns error for invalid MIB name" do
      assert MibTranslator.translate("INVALID-MIB::badObject") == {:error, :translation_failed}
    end

    test "handles empty string" do
      assert MibTranslator.translate("") == {:error, :translation_failed}
    end
  end

  describe "translate_batch/1" do
    # Requires NIF
    # test "translates multiple OIDs" do
    #   mib_names = [
    #     "1.3.6.1.2.1.1.1.0",
    #     "SNMPv2-MIB::sysDescr.0",
    #     "SNMPv2-MIB::sysUpTime.0"
    #   ]
    #
    #   results = MibTranslator.translate_batch(mib_names)
    #
    #   assert map_size(results) == 3
    #   assert {:ok, "1.3.6.1.2.1.1.1.0"} = results["1.3.6.1.2.1.1.1.0"]
    #   assert {:ok, _} = results["SNMPv2-MIB::sysDescr.0"]
    #   assert {:ok, _} = results["SNMPv2-MIB::sysUpTime.0"]
    # end

    # Requires NIF
    # test "handles mix of valid and invalid names" do
    #   mib_names = [
    #     "SNMPv2-MIB::sysDescr.0",
    #     "INVALID-MIB::badObject",
    #     "1.3.6.1.2.1.1.3.0"
    #   ]
    #
    #   results = MibTranslator.translate_batch(mib_names)
    #
    #   assert map_size(results) == 3
    #   assert {:ok, _} = results["SNMPv2-MIB::sysDescr.0"]
    #   assert {:error, :translation_failed} = results["INVALID-MIB::badObject"]
    #   assert {:ok, "1.3.6.1.2.1.1.3.0"} = results["1.3.6.1.2.1.1.3.0"]
    # end

    test "handles empty list" do
      assert MibTranslator.translate_batch([]) == %{}
    end

    test "handles single item" do
      results = MibTranslator.translate_batch(["1.3.6.1.2.1.1.1.0"])

      assert map_size(results) == 1
      assert {:ok, "1.3.6.1.2.1.1.1.0"} = results["1.3.6.1.2.1.1.1.0"]
    end
  end

  describe "numeric OID detection" do
    test "identifies numeric OIDs" do
      assert {:ok, oid} = MibTranslator.translate("1.3.6.1.2.1.1.1.0")
      assert oid == "1.3.6.1.2.1.1.1.0"
    end

    test "identifies numeric OIDs with leading dot" do
      assert {:ok, oid} = MibTranslator.translate(".1.3.6.1.2.1.1.1.0")
      assert oid == ".1.3.6.1.2.1.1.1.0"
    end

    test "identifies single number as OID" do
      assert {:ok, "1"} = MibTranslator.translate("1")
    end

    # Requires NIF
    # test "does not treat MIB names as numeric" do
    #   result = MibTranslator.translate("SNMPv2-MIB::sysDescr.0")
    #   assert {:ok, _} = result
    # end
  end

  describe "MIB directory expansion" do
    @tag :tmp_dir
    test "expands directories with subdirectories", %{tmp_dir: tmp_dir} do
      # Create test directory structure
      File.mkdir_p!(Path.join(tmp_dir, "mibs"))
      File.mkdir_p!(Path.join([tmp_dir, "mibs", "mikrotik"]))
      File.mkdir_p!(Path.join([tmp_dir, "mibs", "cisco"]))
      File.mkdir_p!(Path.join([tmp_dir, "mibs", ".hidden"]))
      File.mkdir_p!(Path.join([tmp_dir, "mibs", "lost+found"]))

      # Set config to use test directory
      Application.put_env(:towerops, :mib_dirs, [Path.join(tmp_dir, "mibs")])

      # Try translation (will fail but exercises expand_mib_directory)
      _result = MibTranslator.translate("TEST-MIB::testObject.0")

      # Cleanup
      Application.delete_env(:towerops, :mib_dirs)
    end

    test "handles nonexistent directory" do
      # Set config to nonexistent directory
      Application.put_env(:towerops, :mib_dirs, ["/nonexistent/path/to/mibs"])

      # Should not crash, just return error
      assert {:error, :translation_failed} =
               MibTranslator.translate("TEST-MIB::testObject.0")

      # Cleanup
      Application.delete_env(:towerops, :mib_dirs)
    end
  end

  describe "error handling" do
    test "handles malformed MIB names gracefully" do
      # Test representative sample (reduced from 4 to 2 for performance)
      malformed_names = [
        "::noModule",
        "MODULE::object::extra"
      ]

      Enum.each(malformed_names, fn name ->
        result = MibTranslator.translate(name)
        assert {:error, _} = result
      end)
    end

    test "handles special characters in names" do
      special_names = [
        "MODULE::object@special",
        "MODULE::object#hash",
        "MODULE::object$dollar"
      ]

      Enum.each(special_names, fn name ->
        result = MibTranslator.translate(name)
        # Should either translate or fail gracefully
        assert match?({:ok, _}, result) or match?({:error, _}, result)
      end)
    end
  end

  describe "standard MIB translations" do
    test "translates IF-MIB objects" do
      # Test representative sample (reduced from 3 to 1 for performance)
      result = MibTranslator.translate("IF-MIB::ifDescr")
      # These should successfully translate or error (if net-snmp not available)
      assert match?({:ok, _}, result) or match?({:error, _}, result)
    end

    test "translates SNMPv2-MIB objects" do
      # Test representative sample (reduced from 3 to 1 for performance)
      result = MibTranslator.translate("SNMPv2-MIB::sysName.0")
      assert match?({:ok, _}, result) or match?({:error, _}, result)
    end
  end

  # All fallback OID registry tests require the NIF to be loaded.
  # Commented out in this worktree.
  #
  # describe "fallback OID registry" do
  #   test "uses fallback for known MikroTik OIDs" do ...
  #   test "uses fallback for MikroTik health OIDs" do ...
  #   test "uses fallback for known Cisco OIDs" do ...
  #   test "uses fallback for ENTITY-MIB OIDs" do ...
  #   test "uses fallback for UCD-SNMP-MIB OIDs (Linux memory)" do ...
  #   test "appends instance suffix when matching base OID" do ...
  #   test "uses fallback for Ubiquiti AirMAX GPS OIDs" do ...
  #   test "uses fallback for Ubiquiti AirMAX host OIDs" do ...
  #   test "uses fallback for Mimosa OIDs" do ...
  #   test "uses fallback for Ubiquiti AirMAX wireless stats OIDs" do ...
  # end
end
