defmodule ToweropsNative do @moduledoc """ NIF wrapper for SNMP MIB resolution using Rust + libnetsnmp. This module provides fast, memory-safe MIB name resolution by wrapping the industry-standard net-snmp library through a Rustler NIF. ## Examples iex> ToweropsNative.resolve_oid("sysDescr") {:ok, "1.3.6.1.2.1.1.1"} iex> ToweropsNative.resolve_oid("IEEE802dot11-MIB::dot11manufacturerProductName") {:ok, "1.2.840.10036.3.1.2.1.3"} ## Performance - MIB loading: 100-500ms at startup (one-time cost) - Resolution: ~2-10µs per OID - Throughput: ~100,000 resolutions/second per core """ use Rustler, otp_app: :towerops, crate: "towerops_native" @doc """ Resolve MIB name to numeric OID string. Accepts both simple names ("sysDescr") and module-qualified names ("SNMPv2-MIB::sysDescr"). The module prefix is stripped before resolution. Returns `{:ok, oid_string}` on success or `{:error, reason}` if the name cannot be resolved. ## Examples iex> ToweropsNative.resolve_oid("sysDescr") {:ok, "1.3.6.1.2.1.1.1"} iex> ToweropsNative.resolve_oid("SNMPv2-MIB::sysDescr") {:ok, "1.3.6.1.2.1.1.1"} iex> ToweropsNative.resolve_oid("invalidMibName") {:error, "Failed to resolve: ..."} """ @spec resolve_oid(String.t()) :: {:ok, String.t()} | {:error, String.t()} def resolve_oid(_mib_name), do: :erlang.nif_error(:nif_not_loaded) @doc """ Load all MIB files from specified directory. This function should be called once at application startup to load all MIB files into memory. Subsequent calls to `resolve_oid/1` will use the loaded MIBs. The MIB loading is performed on a dirty CPU scheduler to avoid blocking the main BEAM schedulers. Returns `:ok` on success or `{:error, reason}` if loading fails. ## Examples iex> ToweropsNative.load_mib_directory("/path/to/mibs") :ok iex> ToweropsNative.load_mib_directory("/invalid/path") {:error, "Failed to load MIBs: ..."} """ @spec load_mib_directory(Path.t()) :: :ok | {:error, String.t()} def load_mib_directory(_path), do: :erlang.nif_error(:nif_not_loaded) @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"`, `"already_initialized"`, or `"initializing"`. ## 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: :erlang.nif_error(:nif_not_loaded) end