"""ASV benchmarks for Temporal Data Model (Revision-Aware RDF).

Measures the performance of:
- TemporalMetadata / TemporalNode / RevisionChain model creation
- InMemoryTemporalBackend revision operations
- Tier-aware temporal queries
- Revision chain traversal
"""

from __future__ import annotations

import importlib
import sys
from datetime import UTC, datetime, timedelta
from pathlib import Path

# Ensure the local *source* tree is importable even when ASV has an
# older build of the package installed.
_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
    sys.path.insert(0, _SRC)

# Force-reload so ASV picks up the source tree version.
import cleveragents  # noqa: E402

importlib.reload(cleveragents)

from cleveragents.domain.models.acms.temporal import (  # noqa: E402
    RevisionChain,
    TemporalMetadata,
    TemporalNode,
    TierRetentionConfig,
)
from cleveragents.domain.models.acms.temporal_stubs import (  # noqa: E402
    InMemoryTemporalBackend,
)
from cleveragents.domain.models.acms.tiers import ContextTier  # noqa: E402
from cleveragents.domain.models.core.project import (  # noqa: E402
    TemporalScope,
)

_NOW = datetime.now(tz=UTC)


# ---------------------------------------------------------------------------
# Model creation benchmarks
# ---------------------------------------------------------------------------


class TemporalModelSuite:
    """Benchmark temporal domain model creation overhead."""

    timeout = 60

    def time_create_temporal_metadata(self) -> None:
        TemporalMetadata(valid_from=_NOW)

    def time_create_temporal_metadata_full(self) -> None:
        TemporalMetadata(
            valid_from=_NOW,
            valid_until=_NOW + timedelta(days=1),
            is_current=False,
            is_revision_of="uko-py:class/Foo_v1",
        )

    def time_create_temporal_node(self) -> None:
        TemporalNode(
            node_uri="uko-py:class/Auth_v1",
            source_resource="RES001",
            source_path="src/auth.py",
            temporal=TemporalMetadata(valid_from=_NOW),
        )

    def time_create_revision_chain(self) -> None:
        RevisionChain(
            current_uri="uko-py:class/Auth_v3",
            predecessors=(
                "uko-py:class/Auth_v1",
                "uko-py:class/Auth_v2",
            ),
        )

    def time_create_tier_retention_config(self) -> None:
        TierRetentionConfig()


# ---------------------------------------------------------------------------
# Backend operation benchmarks
# ---------------------------------------------------------------------------


class TemporalBackendSuite:
    """Benchmark InMemoryTemporalBackend operations."""

    timeout = 60

    def setup(self) -> None:
        """Create a backend with 10 revision chains of 5 versions each."""
        self.backend = InMemoryTemporalBackend()
        self.retention = TierRetentionConfig()

        for chain_idx in range(10):
            base = f"uko-py:class/Chain{chain_idx}"
            prev_uri: str | None = None
            for ver in range(1, 6):
                uri = f"{base}_v{ver}"
                node = TemporalNode(
                    node_uri=uri,
                    source_resource=f"RES{chain_idx:03d}",
                    source_path=f"src/chain{chain_idx}.py",
                    temporal=TemporalMetadata(
                        valid_from=_NOW - timedelta(days=10 - ver),
                        is_current=(ver == 5),
                        is_revision_of=prev_uri,
                        valid_until=(
                            _NOW - timedelta(days=10 - ver - 1) if ver < 5 else None
                        ),
                    ),
                )
                self.backend.store_node(node)
                prev_uri = uri

    def time_get_current(self) -> None:
        self.backend.get_current("uko-py:class/Chain5")

    def time_get_history_all(self) -> None:
        self.backend.get_history(
            "uko-py:class/Chain3",
            TemporalScope.ALL,
        )

    def time_get_history_current(self) -> None:
        self.backend.get_history(
            "uko-py:class/Chain3",
            TemporalScope.CURRENT,
        )

    def time_get_revision_chain(self) -> None:
        self.backend.get_revision_chain("uko-py:class/Chain3_v5")

    def time_query_hot_tier(self) -> None:
        self.backend.query_by_tier(
            ContextTier.HOT,
            TemporalScope.CURRENT,
            self.retention,
        )

    def time_query_cold_tier(self) -> None:
        self.backend.query_by_tier(
            ContextTier.COLD,
            TemporalScope.ALL,
            self.retention,
        )

    def time_create_revision(self) -> None:
        """Benchmark a single revision creation (resets after)."""
        # Store a temporary node to revise
        tmp = TemporalNode(
            node_uri="uko-py:class/Tmp_v1",
            source_resource="RES999",
            source_path="src/tmp.py",
            temporal=TemporalMetadata(
                valid_from=_NOW - timedelta(days=1),
                is_current=True,
            ),
        )
        self.backend.store_node(tmp)

        new = TemporalNode(
            node_uri="uko-py:class/Tmp_v2",
            source_resource="RES999",
            source_path="src/tmp.py",
            temporal=TemporalMetadata(
                valid_from=_NOW,
                is_current=True,
                is_revision_of="uko-py:class/Tmp_v1",
            ),
        )
        self.backend.create_revision(
            "uko-py:class/Tmp_v1",
            new,
            _NOW,
        )

        # Clean up for next iteration
        del self.backend._nodes["uko-py:class/Tmp_v1"]
        del self.backend._nodes["uko-py:class/Tmp_v2"]

    def time_mark_historical(self) -> None:
        """Benchmark marking a node historical (resets after)."""
        tmp = TemporalNode(
            node_uri="uko-py:class/MarkTmp_v1",
            source_resource="RES999",
            source_path="src/tmp.py",
            temporal=TemporalMetadata(
                valid_from=_NOW,
                is_current=True,
            ),
        )
        self.backend.store_node(tmp)
        self.backend.mark_historical("uko-py:class/MarkTmp_v1", _NOW)
        del self.backend._nodes["uko-py:class/MarkTmp_v1"]
