defmodule Pyex.Stdlib do
  @moduledoc """
  Registry of Python standard library modules available to the
  interpreter via `import`.

  Each module is represented as a map of attribute names to values
  (typically `{:builtin, fun}` tuples for callable functions, or
  plain maps for sub-modules).
  """

  @modules %{
    "requests" => Pyex.Stdlib.Requests,
    "json" => Pyex.Stdlib.JSON,
    "math" => Pyex.Stdlib.Math,
    "fastapi" => Pyex.Stdlib.FastAPI,
    "random" => Pyex.Stdlib.Random,
    "re" => Pyex.Stdlib.Re,
    "time" => Pyex.Stdlib.Time,
    "datetime" => Pyex.Stdlib.Datetime,
    "collections" => Pyex.Stdlib.Collections,
    "csv" => Pyex.Stdlib.CSV,
    "html" => Pyex.Stdlib.HTML,
    "itertools" => Pyex.Stdlib.Itertools,
    "jinja2" => Pyex.Stdlib.Jinja2,
    "markdown" => Pyex.Stdlib.Markdown,
    "unittest" => Pyex.Stdlib.Unittest,
    "uuid" => Pyex.Stdlib.UUID,
    "sql" => Pyex.Stdlib.SQL,
    "pydantic" => Pyex.Stdlib.Pydantic,
    "boto3" => Pyex.Stdlib.Boto3,
    "hashlib" => Pyex.Stdlib.Hashlib,
    "hmac" => Pyex.Stdlib.Hmac,
    "base64" => Pyex.Stdlib.Base64,
    "secrets" => Pyex.Stdlib.Secrets,
    "pandas" => Pyex.Stdlib.Pandas,
    "yaml" => Pyex.Stdlib.YAML,
    "decimal" => Pyex.Stdlib.DecimalModule,
    "glob" => Pyex.Stdlib.Glob,
    "pathlib" => Pyex.Stdlib.Pathlib,
    "fnmatch" => Pyex.Stdlib.Fnmatch,
    "urllib" => Pyex.Stdlib.Urllib,
    "shutil" => Pyex.Stdlib.Shutil,
    "dataclasses" => Pyex.Stdlib.Dataclasses,
    "heapq" => Pyex.Stdlib.Heapq,
    "functools" => Pyex.Stdlib.Functools,
    "contextlib" => Pyex.Stdlib.Contextlib,
    "copy" => Pyex.Stdlib.Copy,
    "io" => Pyex.Stdlib.Io,
    "abc" => Pyex.Stdlib.Abc,
    "asyncio" => Pyex.Stdlib.Asyncio,
    "enum" => Pyex.Stdlib.EnumModule,
    "string" => Pyex.Stdlib.String,
    "typing" => Pyex.Stdlib.Typing,
    "textwrap" => Pyex.Stdlib.Textwrap,
    "sys" => Pyex.Stdlib.Sys,
    "crypto" => Pyex.Stdlib.Crypto,
    "zoneinfo" => Pyex.Stdlib.Zoneinfo,
    "operator" => Pyex.Stdlib.Operator,
    "bisect" => Pyex.Stdlib.Bisect,
    "pygments" => Pyex.Stdlib.Pygments,
    "zipfile" => Pyex.Stdlib.Zipfile,
    "statistics" => Pyex.Stdlib.Statistics
  }

  @doc """
  Returns the module value for the given Python module name,
  or `:unknown_module`.
  """
  @spec fetch(String.t()) :: {:ok, Pyex.Stdlib.Module.module_value()} | :unknown_module
  def fetch(name) do
    case Map.fetch(@modules, name) do
      {:ok, mod} -> {:ok, mod.module_value()}
      :error -> :unknown_module
    end
  end

  @doc """
  Returns a sorted list of all available stdlib module names.
  """
  @spec module_names() :: [String.t()]
  def module_names, do: @modules |> Map.keys() |> Enum.sort()
end
