"""ERP adapters — the only place in NEOedge that knows what any vendor calls a field.

NEOedge is an additional module on the customer's existing system: SAP, Microsoft Dynamics,
Oracle, or anything else that can hand over a document. Each names the same fact differently
— `BUKRS`, `DataAreaId` and `ORG_ID` all mean "which company code posted this" — so the
vendor vocabulary lives in a table here, and nothing above this package ever sees it.

Adding an ERP is a table, not a code path (`generic_adapter` makes it a config file). If a
new system seems to need logic rather than a table, that is the grammar missing a concept —
fix the grammar, not the adapter.
"""

from __future__ import annotations

from .base import AdapterError, ErpAdapter, FieldMap
from .dynamics import DYNAMICS_365_FO
from .generic import generic_adapter
from .marketplace import NEOMARK, MarketplaceAdapter, marketplace_adapter, relation_seed
from .oracle import ORACLE_FUSION
from .sap import SAP_S4HANA, from_otlp_attributes

ADAPTERS: dict[str, FieldMap] = {
    SAP_S4HANA.system_id: SAP_S4HANA,
    DYNAMICS_365_FO.system_id: DYNAMICS_365_FO,
    ORACLE_FUSION.system_id: ORACLE_FUSION,
}


def adapter_for(system_id: str) -> ErpAdapter:
    """The adapter for a registered ERP. Anything else is built explicitly with
    `generic_adapter(system_id, columns, doc_kinds)` — never matched fuzzily on field names."""
    field_map = ADAPTERS.get(system_id)
    if field_map is None:
        raise AdapterError(
            "REFUSED_BAD_FIELD",
            f"no adapter for {system_id!r} — registered: {sorted(ADAPTERS)}; "
            "for anything else build one with generic_adapter(system_id, columns, doc_kinds)",
        )
    return ErpAdapter(field_map)


__all__ = [
    "ADAPTERS", "AdapterError", "ErpAdapter", "FieldMap", "MarketplaceAdapter", "NEOMARK",
    "adapter_for", "DYNAMICS_365_FO", "ORACLE_FUSION", "SAP_S4HANA", "from_otlp_attributes",
    "generic_adapter", "marketplace_adapter", "relation_seed",
]
