"""Export graph data from WordLift /dataset/export endpoint."""

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path

import requests
from wordlift_sdk.validation import validate_file

DEFAULT_EXPORT_ENDPOINT = "https://api.wordlift.io/dataset/export"
_DEFAULT_TIMEOUT = 120

_EXTENSION_TO_ACCEPT = {
    ".ttl": "text/turtle",
    ".nt": "application/n-triples",
    ".nq": "application/n-quads",
    ".rdf": "application/rdf+xml",
    ".xml": "application/rdf+xml",
    ".jsonld": "application/ld+json",
    ".json": "application/ld+json",
}


@dataclass
class GraphExportOptions:
    api_key: str
    output_path: Path
    endpoint: str = DEFAULT_EXPORT_ENDPOINT
    timeout: int = _DEFAULT_TIMEOUT


def resolve_accept_header(path: Path) -> str:
    ext = path.suffix.lower()
    accept = _EXTENSION_TO_ACCEPT.get(ext)
    if accept is None:
        supported = ", ".join(sorted(_EXTENSION_TO_ACCEPT))
        raise ValueError(f"Unsupported output extension '{ext or '<none>'}'. Supported: {supported}.")
    return accept


def run_graph_export(options: GraphExportOptions) -> Path:
    accept = resolve_accept_header(options.output_path)
    headers = {
        "Authorization": f"Key {options.api_key}",
        "Accept": accept,
    }
    try:
        response = requests.get(options.endpoint, headers=headers, timeout=options.timeout)
    except requests.RequestException as exc:
        raise RuntimeError(f"Export request failed: {exc}") from exc

    if response.status_code != 200:
        raise RuntimeError(f"Export HTTP {response.status_code}: {response.text[:500]}")

    output_path = options.output_path
    output_path.parent.mkdir(parents=True, exist_ok=True)
    output_path.write_bytes(response.content)
    return output_path


def validate_exported_graph(path: Path) -> None:
    try:
        result = validate_file(str(path), None)
    except Exception as exc:  # pragma: no cover - sdk-specific runtime details
        raise RuntimeError(f"Failed to run SHACL validation: {exc}") from exc

    if not result.conforms:
        raise RuntimeError("Exported graph failed SHACL validation.")
    if result.warning_count:
        raise RuntimeError("Exported graph contains SHACL warnings.")
