defmodule Towerops.Snmp.Profiles.Vendors.Epmp do
  @moduledoc """
  Cambium ePMP device-specific SNMP handling.

  Mirrors LibreNMS/OS/Epmp.php for wireless sensor discovery and hardware detection.

  Supported devices:
  - ePMP AP (Access Point)
  - ePMP SM (Subscriber Module)
  - ePTP Master/Slave
  """

  @behaviour Towerops.Snmp.Profiles.Vendors.Vendor

  alias Towerops.Snmp.Client
  alias Towerops.Snmp.Profiles.Vendors.Vendor

  # OIDs for hardware detection (from CAMBIUM-PMP80211-MIB)
  # wirelessInterfaceMode = { wirelessInterface 1 } = { { wireless 2 } 1 } = 1.3.6.1.4.1.17713.21.3.8.2.1
  @interface_mode_oid "1.3.6.1.4.1.17713.21.3.8.2.1.0"
  # cambiumSubModeType = { cambiumGeneralStatus 33 } = 1.3.6.1.4.1.17713.21.1.1.33
  @sub_mode_oid "1.3.6.1.4.1.17713.21.1.1.33.0"

  @impl true
  def profile_names, do: ["epmp"]

  @impl true
  def detect_hardware(client_opts) do
    with {:ok, interface_mode} <- Client.get(client_opts, @interface_mode_oid),
         {:ok, sub_mode} <- Client.get(client_opts, @sub_mode_oid) do
      case {interface_mode, sub_mode} do
        # AP mode
        {1, 5} -> "ePTP Master"
        {1, _} -> "ePMP AP"
        # SM mode
        {2, 4} -> "ePTP Slave"
        {2, _} -> "ePMP SM"
        _ -> nil
      end
    else
      _ -> nil
    end
  end

  @impl true
  def discover_wireless_sensors(client_opts) do
    Vendor.fetch_sensors(wireless_oid_defs(), client_opts)
  end

  @impl true
  def wireless_oid_defs do
    [
      # === Wireless sensors (from discoverWireless* methods) ===
      # RSSI in dBm (SM only - will be "No Such Instance" on AP)
      %{
        oid: "1.3.6.1.4.1.17713.21.1.2.3.0",
        sensor_type: "rssi",
        sensor_descr: "RSSI",
        sensor_unit: "dBm",
        sensor_divisor: 1
      },
      # SNR in dB (SM only - will be "No Such Instance" on AP)
      %{
        oid: "1.3.6.1.4.1.17713.21.1.2.18.0",
        sensor_type: "snr",
        sensor_descr: "SNR",
        sensor_unit: "dB",
        sensor_divisor: 1
      },
      # Frequency in MHz
      %{
        oid: "1.3.6.1.4.1.17713.21.1.2.1.0",
        sensor_type: "frequency",
        sensor_descr: "Frequency",
        sensor_unit: "MHz",
        sensor_divisor: 1
      },
      # Connected clients count (AP only)
      %{
        oid: "1.3.6.1.4.1.17713.21.1.2.10.0",
        sensor_type: "clients",
        sensor_descr: "Connected Clients",
        sensor_unit: "",
        sensor_divisor: 1
      },
      # === GPS sensors (from pollOS) ===
      # GPS Tracked Satellites
      %{
        oid: "1.3.6.1.4.1.17713.21.1.2.64.0",
        sensor_type: "count",
        sensor_descr: "GPS Tracked Satellites",
        sensor_unit: "",
        sensor_divisor: 1
      },
      # GPS Visible Satellites
      %{
        oid: "1.3.6.1.4.1.17713.21.1.2.65.0",
        sensor_type: "count",
        sensor_descr: "GPS Visible Satellites",
        sensor_unit: "",
        sensor_divisor: 1
      },
      # === Radio settings ===
      # Transmit Power in dBm
      %{
        oid: "1.3.6.1.4.1.17713.21.1.2.5.0",
        sensor_type: "power",
        sensor_descr: "Transmit Power",
        sensor_unit: "dBm",
        sensor_divisor: 1
      },
      # Channel Width in MHz
      %{
        oid: "1.3.6.1.4.1.17713.21.1.1.20.0",
        sensor_type: "frequency",
        sensor_descr: "Channel Width",
        sensor_unit: "MHz",
        sensor_divisor: 1
      },
      # === Network entry stats (from pollOS) ===
      # Network Entry Attempts
      %{
        oid: "1.3.6.1.4.1.17713.21.2.1.33.0",
        sensor_type: "count",
        sensor_descr: "Network Entry Attempts",
        sensor_unit: "",
        sensor_divisor: 1
      },
      # Network Entry Success
      %{
        oid: "1.3.6.1.4.1.17713.21.2.1.34.0",
        sensor_type: "count",
        sensor_descr: "Network Entry Success",
        sensor_unit: "",
        sensor_divisor: 1
      },
      # Authentication Failures
      %{
        oid: "1.3.6.1.4.1.17713.21.2.1.35.0",
        sensor_type: "count",
        sensor_descr: "Auth Failures",
        sensor_unit: "",
        sensor_divisor: 1
      }
    ]
  end
end
