from __future__ import annotations

import json
from functools import lru_cache
from pathlib import Path

import pytest

from src.fmatch.saas.operators.company_to_domain import company_to_domain
from src.fmatch.saas.operators.email_domain_match import email_domain_match
from src.fmatch.saas.operators.wikidata_index import HAS_DUCKDB, get_wikidata_index

FIXTURE_PATH = (
    Path(__file__).resolve().parent
    / "fixtures"
    / "company_domain_named_entity_snapshot.json"
)


def _load_cases() -> list[dict[str, object]]:
    with FIXTURE_PATH.open("r", encoding="utf-8") as handle:
        return json.load(handle)


CASES = _load_cases()


@lru_cache(maxsize=1)
def _wikidata_available() -> bool:
    if not HAS_DUCKDB:
        return False
    return bool(get_wikidata_index())


def _require_case_provider(case: dict[str, object]) -> None:
    if case.get("current_source") == "wikidata" and not _wikidata_available():
        pytest.skip("Wikidata snapshot cases require config/foundrygraph.duckdb")


def test_named_entity_snapshot_fixture_shape() -> None:
    assert len(CASES) == 50
    companies = [str(case["company"]) for case in CASES]
    assert len(set(companies)) == len(companies)


@pytest.mark.parametrize("case", CASES, ids=lambda case: str(case["company"]))
def test_company_to_domain_named_entity_snapshot(case: dict[str, object]) -> None:
    _require_case_provider(case)

    result = company_to_domain(str(case["company"]))
    value = result.get("value", {})
    actual_domain = value.get("domain", "")
    expected_domain = case["current_domain"]

    assert actual_domain == expected_domain, (
        f"{case['company']} snapshot drifted: expected {expected_domain!r}, "
        f"got {actual_domain!r}. Target contract is {case.get('target_domain')!r}."
    )


@pytest.mark.parametrize(
    "case",
    [case for case in CASES if case.get("target_domain")],
    ids=lambda case: str(case["company"]),
)
def test_email_domain_match_named_entity_snapshot(case: dict[str, object]) -> None:
    _require_case_provider(case)

    target_domain = str(case["target_domain"])
    result = email_domain_match(
        {"email": f"sales@{target_domain}", "company": str(case["company"])}
    )

    assert result["value"] is case["current_email_match_with_target_domain"], (
        f"{case['company']} email-domain snapshot drifted for {target_domain!r}. "
        f"Expected {case['current_email_match_with_target_domain']!r}, "
        f"got {result['value']!r}."
    )
