"""GENERATED by witgen — DO NOT EDIT.

Re-generate with: uv run python -m tools.witgen
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Callable

from wasmtime import Store
from wasmtime import component as cm

# FIXME(wasmtime-py): v40 does not export these from a public path;
# wasmtime.component._types is the only way to access them.  Revisit when
# wasmtime-py exposes a public API for component-model types.
from wasmtime.component._types import (
    OptionType,
    ResultType,
    VariantLikeType,
    VariantType,
)

from ._convert import (
    to_wasm_sensitive_info_entity,
)
from ._types import (
    SensitiveInfoEntity,
)

# FIXME(wasmtime-py): v40 MRO bug workaround — remove when fixed upstream.
try:
    _real_add_classes = VariantLikeType.add_classes
    for _cls in (VariantType, OptionType, ResultType):
        if _cls.add_classes is not _real_add_classes:
            _cls.add_classes = _real_add_classes  # type: ignore[assignment]
except (AttributeError, TypeError):
    pass  # Future wasmtime-py may fix this or restructure these classes


@dataclass(frozen=True, slots=True)
class ImportCallbacks:
    """User-provided callbacks for component import interfaces."""

    is_free_email: Callable[[str], str] | None = None
    is_disposable_email: Callable[[str], str] | None = None
    has_mx_records: Callable[[str], str] | None = None
    has_gravatar: Callable[[str], str] | None = None
    sensitive_info_detect: Callable[[list[str]], list[SensitiveInfoEntity | None]] | None = None
    bot_verify: Callable[[str, str], str] | None = None
    bot_detect: Callable[[str], list[str]] | None = None
    ip_lookup: Callable[[str], str | None] | None = None


def wire_imports(
    linker: cm.Linker,
    component: cm.Component,
    callbacks: ImportCallbacks | None = None,
) -> None:
    """Wire all import interfaces into *linker* using trap-then-shadow."""
    cb = callbacks or ImportCallbacks()

    # 1. Trap everything first
    linker.define_unknown_imports_as_traps(component)

    from ._import_defaults import (
        _default_bot_detect,
        _default_bot_verify,
        _default_has_gravatar,
        _default_has_mx_records,
        _default_ip_lookup,
        _default_is_disposable_email,
        _default_is_free_email,
        _default_sensitive_info_detect,
    )

    is_free_email_fn = cb.is_free_email or _default_is_free_email
    is_disposable_email_fn = cb.is_disposable_email or _default_is_disposable_email
    has_mx_records_fn = cb.has_mx_records or _default_has_mx_records
    has_gravatar_fn = cb.has_gravatar or _default_has_gravatar
    sensitive_info_detect_fn = cb.sensitive_info_detect or _default_sensitive_info_detect
    bot_verify_fn = cb.bot_verify or _default_bot_verify
    bot_detect_fn = cb.bot_detect or _default_bot_detect
    ip_lookup_fn = cb.ip_lookup or _default_ip_lookup

    # 2. Override with real implementations
    with linker.root() as root:
        with root.add_instance("arcjet:js-req/email-validator-overrides") as iface:
            iface.add_func("is-free-email", lambda _store, a: is_free_email_fn(a))
            iface.add_func("is-disposable-email", lambda _store, a: is_disposable_email_fn(a))
            iface.add_func("has-mx-records", lambda _store, a: has_mx_records_fn(a))
            iface.add_func("has-gravatar", lambda _store, a: has_gravatar_fn(a))

        with root.add_instance("arcjet:js-req/sensitive-information-identifier") as iface:

            def _wrap_sensitive_info_detect(_store: Store, tokens: list[str]):
                results = sensitive_info_detect_fn(tokens)
                if len(results) != len(tokens):
                    raise ValueError("callback returned %d results, expected %d" % (len(results), len(tokens)))
                return [None if _r is None else to_wasm_sensitive_info_entity(_r) for _r in results]

            iface.add_func("detect", _wrap_sensitive_info_detect)

        with root.add_instance("arcjet:js-req/verify-bot") as iface:
            iface.add_func("verify", lambda _store, a, b: bot_verify_fn(a, b))

        with root.add_instance("arcjet:js-req/bot-identifier") as iface:
            iface.add_func("detect", lambda _store, a: bot_detect_fn(a))

        with root.add_instance("arcjet:js-req/filter-overrides") as iface:
            iface.add_func("ip-lookup", lambda _store, a: ip_lookup_fn(a))

