"""ASV benchmarks for Session domain model validation and serialization.

Measures the performance of:
- Session model construction (Pydantic validation)
- SessionMessage construction
- Session.append_message() auto-sequencing
- Session.as_cli_dict() serialization
- Session.as_export_dict() serialization with checksum
- SessionTokenUsage construction
- Session.get_messages() with pagination
"""

from __future__ import annotations

import sys
from pathlib import Path

try:
    from cleveragents.domain.models.core.session import (
        MessageRole,
        Session,
        SessionMessage,
        SessionTokenUsage,
    )
except ModuleNotFoundError:
    sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
    from cleveragents.domain.models.core.session import (
        MessageRole,
        Session,
        SessionMessage,
        SessionTokenUsage,
    )

from ulid import ULID


def _make_session(message_count: int = 0) -> Session:
    """Create a Session with optional messages for benchmarking."""
    session = Session(session_id=str(ULID()))
    for i in range(message_count):
        session.append_message(MessageRole.USER, f"Benchmark message {i}")
    return session


def _make_message() -> SessionMessage:
    """Create a fully-populated SessionMessage for benchmarking."""
    return SessionMessage(
        message_id=str(ULID()),
        role=MessageRole.USER,
        content="Benchmark message content",
        sequence=0,
        metadata={"key": "value"},
    )


class SessionValidationSuite:
    """Benchmark Session model construction (Pydantic validation)."""

    def time_session_construction(self) -> None:
        """Benchmark creating a minimal Session object."""
        Session(session_id=str(ULID()))

    def time_session_with_actor(self) -> None:
        """Benchmark creating a Session with actor_name."""
        Session(session_id=str(ULID()), actor_name="local/orchestrator")

    def time_message_construction(self) -> None:
        """Benchmark creating a SessionMessage."""
        _make_message()

    def time_tool_message_construction(self) -> None:
        """Benchmark creating a tool SessionMessage with tool_call_id."""
        SessionMessage(
            message_id=str(ULID()),
            role=MessageRole.TOOL,
            content="Tool result",
            sequence=0,
            tool_call_id="call_123",
        )

    def time_token_usage_construction(self) -> None:
        """Benchmark SessionTokenUsage construction."""
        SessionTokenUsage(
            input_tokens=1000,
            output_tokens=500,
            estimated_cost=0.05,
        )


class SessionAppendSuite:
    """Benchmark Session.append_message() auto-sequencing."""

    def setup(self) -> None:
        """Create a session for append benchmarks."""
        self.session = _make_session()

    def time_append_single_message(self) -> None:
        """Benchmark appending a single message."""
        self.session.append_message(MessageRole.USER, "Benchmark message")

    def time_append_10_messages(self) -> None:
        """Benchmark appending 10 messages sequentially."""
        session = _make_session()
        for i in range(10):
            session.append_message(MessageRole.USER, f"Message {i}")


class SessionSerializationSuite:
    """Benchmark Session serialization methods."""

    def setup(self) -> None:
        """Create a session with messages for serialization benchmarks."""
        self.session = _make_session(message_count=10)
        self.session.link_plan(str(ULID()))
        self.large_session = _make_session(message_count=100)

    def time_as_cli_dict(self) -> None:
        """Benchmark Session.as_cli_dict() ordered dict generation."""
        self.session.as_cli_dict()

    def time_as_export_dict(self) -> None:
        """Benchmark Session.as_export_dict() with checksum generation."""
        self.session.as_export_dict()

    def time_as_export_dict_large(self) -> None:
        """Benchmark export dict for a large session (100 messages)."""
        self.large_session.as_export_dict()

    def time_model_dump(self) -> None:
        """Benchmark Pydantic model_dump() serialization."""
        self.session.model_dump()

    def time_model_dump_json(self) -> None:
        """Benchmark Pydantic model_dump_json() JSON serialization."""
        self.session.model_dump_json()


class SessionPaginationSuite:
    """Benchmark Session.get_messages() with pagination."""

    def setup(self) -> None:
        """Create a session with many messages for pagination benchmarks."""
        self.session = _make_session(message_count=100)

    def time_get_all_messages(self) -> None:
        """Benchmark getting all messages (no limit)."""
        self.session.get_messages()

    def time_get_first_10(self) -> None:
        """Benchmark getting first 10 messages."""
        self.session.get_messages(limit=10)

    def time_get_with_offset(self) -> None:
        """Benchmark getting messages with offset."""
        self.session.get_messages(limit=10, offset=50)
