from __future__ import annotations

from pathlib import Path

from fastgws.errors import ValidationError
from fastgws.helpers import project_root

from .emit_docs import _signature, emit_docs
from .emit_meta import render_registry, render_service_module
from .emit_pyi import emit_pyi
from .manifest import fixture_path, load_manifest
from .normalize import load_fixture_doc, normalize_service


def check_generated(root: str | Path | None = None):
    root = project_root(root)
    services = [normalize_service(entry, load_fixture_doc(fixture_path(entry, root))) for entry in load_manifest(root)]
    for service in services:
        current = (root / "fastgws" / "generated" / f"{service.alias}_meta.py").read_text()
        expected = render_service_module(service)
        if current != expected:
            raise ValidationError(f"generated metadata is stale for {service.alias}")
    registry = (root / "fastgws" / "generated" / "registry.py").read_text()
    if registry != render_registry(services):
        raise ValidationError("generated registry is stale")
    docs_index = (root / "docs" / "api" / "index.md").read_text()
    expected_index = "# API Reference\n\n" + "\n".join(f"- [{service.title}]({service.alias}.md)" for service in services) + "\n"
    if docs_index != expected_index:
        raise ValidationError("generated docs index is stale")
    for service in services:
        page = (root / "docs" / "api" / f"{service.alias}.md").read_text()
        expected = _render_doc_page(service)
        if page != expected:
            raise ValidationError(f"generated docs are stale for {service.alias}")
    stub = (root / "fastgws" / "generated" / "services.pyi").read_text()
    if not stub.strip():
        raise ValidationError("generated stubs are stale")


def _render_doc_page(service):
    lines = [f"# {service.title}", "", service.description, ""]
    if service.documentation_link:
        lines += [f"Docs: {service.documentation_link}", ""]
    lines += ["## Methods", ""]
    for method in service.methods:
        lines += [f"### `{method.dotted_path}`", "", f"`{_signature(method)}`", ""]
        if method.description:
            lines += [method.description, ""]
    return "\n".join(lines).rstrip() + "\n"
