"""Integration tests against real-world spec/ directory."""

from pathlib import Path

import pytest

from elspais.config import load_config
from elspais.graph import NodeKind
from elspais.graph.builder import GraphBuilder
from elspais.graph.deserializer import DomainFile
from elspais.graph.parsers.lark import FileDispatcher
from elspais.utilities.patterns import build_resolver

# Get repo root (3 levels up from this test file)
REPO_ROOT = Path(__file__).parent.parent.parent.parent
SPEC_DIR = REPO_ROOT / "spec"
CONFIG_FILE = REPO_ROOT / ".elspais.toml"


@pytest.fixture
def real_resolver():
    """Load IdResolver from the real .elspais.toml."""
    if not CONFIG_FILE.exists():
        pytest.skip("No .elspais.toml found in repo root")

    config = load_config(CONFIG_FILE)
    return build_resolver(config)


@pytest.fixture
def dispatcher(real_resolver):
    """Create Lark FileDispatcher for spec file parsing."""
    return FileDispatcher(real_resolver)


class TestRealWorldSpecs:
    """Tests against the actual spec/ directory."""

    # Implements: REQ-p00013-C
    def test_spec_directory_exists(self):
        """Verify spec directory exists for testing."""
        if not SPEC_DIR.exists():
            pytest.skip("No spec/ directory found")
        assert SPEC_DIR.is_dir()

    # Implements: REQ-p00013-C
    def test_can_parse_spec_files(self, dispatcher):
        """Verify parser can process real spec files."""
        if not SPEC_DIR.exists():
            pytest.skip("No spec/ directory found")

        deserializer = DomainFile(SPEC_DIR, patterns=["*.md"])
        results = list(deserializer.dispatch(dispatcher.dispatch_spec))

        # Should get some parsed content
        assert len(results) > 0

    # Implements: REQ-p00013-C
    def test_finds_prd_requirements(self, dispatcher):
        """Verify PRD requirements are found in real specs."""
        if not SPEC_DIR.exists():
            pytest.skip("No spec/ directory found")

        deserializer = DomainFile(SPEC_DIR, patterns=["*.md"])

        builder = GraphBuilder(repo_root=REPO_ROOT)
        for content in deserializer.dispatch(dispatcher.dispatch_spec):
            builder.add_parsed_content(content)

        graph = builder.build()

        # The real spec has REQ-p00001, REQ-p00002, etc.
        prd_reqs = [
            n for n in graph.nodes_by_kind(NodeKind.REQUIREMENT) if n.id.startswith("REQ-p")
        ]

        # Should find at least one PRD requirement
        assert len(prd_reqs) > 0

    # Implements: REQ-p00013-C
    def test_graph_has_roots(self, dispatcher):
        """Verify graph identifies root requirements."""
        if not SPEC_DIR.exists():
            pytest.skip("No spec/ directory found")

        deserializer = DomainFile(SPEC_DIR, patterns=["*.md"])

        builder = GraphBuilder(repo_root=REPO_ROOT)
        for content in deserializer.dispatch(dispatcher.dispatch_spec):
            builder.add_parsed_content(content)

        graph = builder.build()

        # Should have at least one root (top-level PRD req)
        assert graph.root_count() > 0

    # Implements: REQ-p00013-C
    def test_assertions_are_created(self, dispatcher):
        """Verify assertions are extracted from requirements."""
        if not SPEC_DIR.exists():
            pytest.skip("No spec/ directory found")

        deserializer = DomainFile(SPEC_DIR, patterns=["*.md"])

        builder = GraphBuilder(repo_root=REPO_ROOT)
        for content in deserializer.dispatch(dispatcher.dispatch_spec):
            builder.add_parsed_content(content)

        graph = builder.build()

        assertions = list(graph.nodes_by_kind(NodeKind.ASSERTION))

        # Real specs have assertions (A, B, C, etc.)
        assert len(assertions) > 0

    # Implements: REQ-p00013-C
    def test_implements_relationships(self, dispatcher):
        """Verify implements relationships are parsed."""
        if not SPEC_DIR.exists():
            pytest.skip("No spec/ directory found")

        deserializer = DomainFile(SPEC_DIR, patterns=["*.md"])

        builder = GraphBuilder(repo_root=REPO_ROOT)
        for content in deserializer.dispatch(dispatcher.dispatch_spec):
            builder.add_parsed_content(content)

        graph = builder.build()

        # Count requirements with parents (i.e., they implement something)
        reqs_with_parents = [n for n in graph.nodes_by_kind(NodeKind.REQUIREMENT) if not n.is_root]

        # Should have at least some hierarchical relationships
        # (e.g., REQ-p00002 implements REQ-p00001)
        assert len(reqs_with_parents) > 0
