defmodule Towerops.Snmp.MibTranslator do
  @moduledoc """
  Translates MIB names to numeric OIDs using the net-snmp C NIF.

  This module wraps `ToweropsNative.resolve_oid/1` and provides a consistent
  API for MIB name translation throughout the application.
  """

  @doc """
  Translates a single MIB name to a numeric OID.

  Returns `{:ok, oid}` on success or `{:error, :translation_failed}` on failure.

  Numeric OIDs (with or without leading dots) are returned unchanged.

  ## Examples

      iex> MibTranslator.translate("SNMPv2-MIB::sysDescr.0")
      {:ok, "1.3.6.1.2.1.1.1.0"}

      iex> MibTranslator.translate("1.3.6.1.2.1.1.1.0")
      {:ok, "1.3.6.1.2.1.1.1.0"}

      iex> MibTranslator.translate(".1.3.6.1.2.1.1.1.0")
      {:ok, ".1.3.6.1.2.1.1.1.0"}

      iex> MibTranslator.translate("INVALID-MIB::badObject")
      {:error, :translation_failed}
  """
  @spec translate(String.t()) :: {:ok, String.t()} | {:error, :translation_failed}
  def translate(mib_name) when is_binary(mib_name) do
    cond do
      # Empty string
      mib_name == "" ->
        {:error, :translation_failed}

      # Numeric OID with leading dot - return as-is
      String.match?(mib_name, ~r/^\.\d+(\.\d+)*$/) ->
        {:ok, mib_name}

      # Numeric OID without leading dot - return as-is
      String.match?(mib_name, ~r/^\d+(\.\d+)*$/) ->
        {:ok, mib_name}

      # MIB name - use C NIF to translate
      true ->
        case ToweropsNative.resolve_oid(mib_name) do
          oid when is_binary(oid) ->
            {:ok, oid}

          {:error, _reason} ->
            {:error, :translation_failed}
        end
    end
  end

  @doc """
  Translates multiple MIB names to numeric OIDs in a single batch operation.

  Returns a map where each key is a MIB name and the value is either
  `{:ok, oid}` or `{:error, :translation_failed}`.

  ## Examples

      iex> MibTranslator.translate_batch(["SNMPv2-MIB::sysDescr.0", "1.3.6.1.2.1.1.3.0"])
      %{
        "SNMPv2-MIB::sysDescr.0" => {:ok, "1.3.6.1.2.1.1.1.0"},
        "1.3.6.1.2.1.1.3.0" => {:ok, "1.3.6.1.2.1.1.3.0"}
      }
  """
  @spec translate_batch([String.t()]) :: %{String.t() => {:ok, String.t()} | {:error, :translation_failed}}
  def translate_batch(mib_names) when is_list(mib_names) do
    Map.new(mib_names, fn mib_name ->
      {mib_name, translate(mib_name)}
    end)
  end
end
