"""Module-level singleton for AnalyzeComponent.

Hand-maintained — not generated by witgen.

Usage::

    from arcjet._analyze import get_component

    component = get_component()          # lazy init with defaults
    result = component.detect_bot(...)

Tests can use the constructor directly for isolation, or call
``reset_component()`` to clear the cached singleton.
"""

from __future__ import annotations

import os
import threading

from ._imports import ImportCallbacks
from ._overrides import AnalyzeComponent

_instance: AnalyzeComponent | None = None
_instance_lock = threading.Lock()


def _default_wasm_path() -> str:
    return os.path.join(
        os.path.dirname(__file__),
        "wasm",
        "arcjet_analyze_js_req.component.wasm",
    )


def get_component(
    wasm_path: str | None = None,
    callbacks: ImportCallbacks | None = None,
) -> AnalyzeComponent:
    """Return the singleton AnalyzeComponent, creating it on first call.

    *wasm_path* and *callbacks* are only used on the **first** call that
    creates the instance.  Subsequent calls return the cached instance and
    ignore these arguments.

    For tests that need a fresh instance, use the ``AnalyzeComponent``
    constructor directly or call :func:`reset_component` first.
    """
    global _instance
    # Fast path — no lock needed once initialised.
    if _instance is not None:
        return _instance
    with _instance_lock:
        # Double-checked locking.
        if _instance is not None:
            return _instance
        _instance = AnalyzeComponent(
            wasm_path or _default_wasm_path(),
            callbacks,
        )
        return _instance


def reset_component() -> None:
    """Close and discard the singleton, allowing re-initialisation.

    Safe to call even if no singleton has been created yet.
    Primarily intended for test teardown.
    """
    global _instance
    with _instance_lock:
        if _instance is not None:
            _instance.close()
            _instance = None
