"""Shared fixtures for contract & chaos tests."""
from __future__ import annotations

import csv
from pathlib import Path

import pytest

# ---------------------------------------------------------------------------
# Capability detection
# ---------------------------------------------------------------------------
# The installed kanoniv package uses a Rust native extension (_native).
# Spec/validate/plan/diff need: parse, validate, plan, diff from _native
# reconcile needs: reconcile_local from _native (may not be present)

try:
    from kanoniv._native import parse as _parse  # noqa: F401

    HAS_NATIVE = True
except (ImportError, AttributeError):
    HAS_NATIVE = False

try:
    from kanoniv._native import reconcile_local  # noqa: F401

    HAS_RECONCILE = True
except (ImportError, AttributeError):
    HAS_RECONCILE = False

requires_native = pytest.mark.skipif(
    not HAS_NATIVE, reason="Native extension not built"
)

requires_reconcile = pytest.mark.skipif(
    not HAS_RECONCILE, reason="reconcile_local not available in native extension"
)

# ---------------------------------------------------------------------------
# Golden dataset helpers
# ---------------------------------------------------------------------------

GOLDEN_DIR = Path(__file__).parent / "golden"


def golden_path(filename: str) -> str:
    """Return absolute path to a golden CSV file."""
    return str(GOLDEN_DIR / filename)


# ---------------------------------------------------------------------------
# Spec YAML constants
# ---------------------------------------------------------------------------

MINIMAL_VALID_SPEC = """\
api_version: kanoniv/v2
identity_version: test_v1.0
entity:
  name: customer
sources:
  - name: src_a
    system: csv
    table: src_a
    id: id
    attributes:
      email: email
blocking:
  strategy: composite
  keys:
    - [email]
rules:
  - name: email_exact
    type: exact
    field: email
    weight: 1.0
decision:
  thresholds:
    match: 0.7
    review: 0.4
  conflict_strategy: prefer_high_confidence
"""

CUSTOMER_SPEC = """\
api_version: kanoniv/v2
identity_version: test_v1.0
entity:
  name: customer
sources:
  - name: crm
    system: csv
    table: crm_contacts
    id: id
    attributes:
      email: email
      first_name: first_name
      last_name: last_name
      phone: phone
  - name: ecommerce
    system: csv
    table: ecommerce_orders
    id: id
    attributes:
      email: email
      first_name: first_name
      last_name: last_name
      phone: phone
blocking:
  strategy: composite
  keys:
    - [email]
    - [phone]
rules:
  - name: email_exact
    type: exact
    field: email
    weight: 1.0
  - name: phone_exact
    type: exact
    field: phone
    weight: 0.8
decision:
  thresholds:
    match: 0.5
    review: 0.3
  conflict_strategy: prefer_high_confidence
"""

# Single-source version for simpler tests
SINGLE_SOURCE_SPEC = """\
api_version: kanoniv/v2
identity_version: test_v1.0
entity:
  name: customer
sources:
  - name: main
    system: csv
    table: main
    id: id
    attributes:
      email: email
      first_name: first_name
      last_name: last_name
      phone: phone
blocking:
  strategy: composite
  keys:
    - [email]
    - [phone]
rules:
  - name: email_exact
    type: exact
    field: email
    weight: 1.0
  - name: phone_exact
    type: exact
    field: phone
    weight: 0.8
decision:
  thresholds:
    match: 0.4
    review: 0.2
  conflict_strategy: prefer_high_confidence
"""


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


def make_spec(yaml_str: str):
    """Create a Spec from a YAML string."""
    from kanoniv.spec import Spec

    return Spec.from_string(yaml_str)


def make_csv(tmp_path: Path, name: str, rows: list[dict]) -> str:
    """Write rows to a CSV file and return the path."""
    path = tmp_path / f"{name}.csv"
    if not rows:
        path.write_text("")
        return str(path)
    fieldnames = list(rows[0].keys())
    with open(path, "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(rows)
    return str(path)


def make_source(tmp_path: Path, name: str, rows: list[dict], primary_key: str = "id"):
    """Create a Source.from_csv() from row dicts in one call."""
    from kanoniv.source import Source

    csv_path = make_csv(tmp_path, name, rows)
    return Source.from_csv(name, csv_path, primary_key=primary_key)
