defmodule ToweropsNative do
  @moduledoc """
  NIF wrapper for SNMP MIB resolution using pure C + libnetsnmp.

  This module provides fast MIB name resolution by directly calling
  the industry-standard net-snmp library through a pure C NIF (no Rust layer).

  ## Examples

      iex> ToweropsNative.resolve_oid("sysDescr")
      "1.3.6.1.2.1.1.1"

      iex> ToweropsNative.resolve_oid("IF-MIB::ifDescr")
      "1.3.6.1.2.1.2.2.1.2"

  ## Performance

  - MIB loading: ~1-2 seconds at startup (one-time cost)
  - Resolution: ~1-20µs per OID (in-memory lookups)
  - Throughput: ~50,000-100,000 resolutions/second per core
  """

  @on_load :load_nif

  def load_nif do
    nif_path = :filename.join(:code.priv_dir(:towerops), ~c"towerops_nif")

    case :erlang.load_nif(nif_path, 0) do
      :ok ->
        :ok

      {:error, _reason} ->
        require Logger

        Logger.warning("ToweropsNative NIF not available, using stubs")
        :ok
    end
  end

  @doc """
  Resolve MIB name to numeric OID string.

  Accepts both simple names ("sysDescr") and module-qualified names
  ("SNMPv2-MIB::sysDescr").

  Returns the numeric OID string on success or `{:error, reason}` if the
  name cannot be resolved.

  ## Examples

      iex> ToweropsNative.resolve_oid("sysDescr")
      "1.3.6.1.2.1.1.1"

      iex> ToweropsNative.resolve_oid("SNMPv2-MIB::sysDescr")
      "1.3.6.1.2.1.1.1"

      iex> ToweropsNative.resolve_oid("invalidMibName")
      {:error, "Failed to resolve MIB name"}
  """
  @spec resolve_oid(String.t()) :: String.t() | {:error, String.t()}
  def resolve_oid(_mib_name), do: {:error, "NIF not loaded"}

  @doc """
  Add a MIB directory to the search path.

  This function should be called once at application startup to configure
  where net-snmp should look for MIB files.

  Returns `:ok` on success.

  ## Examples

      iex> ToweropsNative.load_mib_directory("/path/to/mibs")
      :ok
  """
  @spec load_mib_directory(Path.t()) :: :ok
  def load_mib_directory(_path), do: :ok

  @doc """
  Initialize the net-snmp library and load all MIBs into memory.

  This function is called automatically on the first call to `resolve_oid/1`,
  so you typically don't need to call it explicitly. However, you can call it
  during application startup to warm up the MIB cache.

  The initialization is performed on a dirty CPU scheduler to avoid blocking
  the main BEAM schedulers.

  Returns `"initialized"` or `"already_initialized"`.

  ## Examples

      iex> ToweropsNative.init_mib_library()
      "initialized"

      iex> ToweropsNative.init_mib_library()
      "already_initialized"
  """
  @spec init_mib_library() :: String.t()
  def init_mib_library, do: "initialized"
end
