"""ASV benchmarks for session persistence (repository + service layer).

Measures the performance of:
- SessionRepository.create() round-trip
- SessionRepository.get_by_id() lookup
- SessionRepository.list_all() listing
- SessionMessageRepository.append() single message
- SessionMessageRepository.get_for_session() retrieval
- PersistentSessionService.export_session() with messages
- PersistentSessionService.import_session() from export dict
- PersistentSessionService.update_token_usage()
"""

from __future__ import annotations

import sys
from pathlib import Path

try:
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
except ModuleNotFoundError:
    sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker

from cleveragents.application.services.session_service import (
    PersistentSessionService,
)
from cleveragents.domain.models.core.session import MessageRole
from cleveragents.infrastructure.database.models import Base
from cleveragents.infrastructure.database.repositories import (
    SessionMessageRepository,
    SessionRepository,
)


def _make_service():
    """Create in-memory DB and service."""
    engine = create_engine("sqlite:///:memory:", echo=False)
    Base.metadata.create_all(engine)
    factory = sessionmaker(bind=engine, expire_on_commit=False)
    db_session = factory()

    def get_session():
        return db_session

    session_repo = SessionRepository(get_session)
    message_repo = SessionMessageRepository(get_session)
    svc = PersistentSessionService(session_repo, message_repo)
    return svc, db_session


class SessionPersistenceSuite:
    """Benchmark session persistence operations."""

    def setup(self):
        self.svc, self.db_session = _make_service()
        self.session = self.svc.create()
        self.db_session.commit()
        # Pre-populate messages for retrieval benchmarks
        for i in range(20):
            self.svc.append_message(
                self.session.session_id,
                MessageRole.USER,
                f"Benchmark message {i}",
            )
            self.db_session.commit()

    def time_session_create(self):
        """Benchmark creating a new session."""
        self.svc.create()
        self.db_session.commit()

    def time_session_get_by_id(self):
        """Benchmark getting a session by ID."""
        self.svc.get(self.session.session_id)

    def time_session_list_all(self):
        """Benchmark listing all sessions."""
        self.svc.list()

    def time_message_append(self):
        """Benchmark appending a single message."""
        self.svc.append_message(
            self.session.session_id,
            MessageRole.USER,
            "Benchmark append",
        )
        self.db_session.commit()

    def time_export_session(self):
        """Benchmark exporting a session with 20 messages."""
        self.svc.export_session(self.session.session_id)

    def time_update_token_usage(self):
        """Benchmark updating token usage."""
        self.svc.update_token_usage(self.session.session_id, 100, 50, 0.005)
        self.db_session.commit()


class SessionImportSuite:
    """Benchmark session import operations."""

    def setup(self):
        self.svc, self.db_session = _make_service()
        session = self.svc.create(actor_name="local/bench-actor")
        self.db_session.commit()
        for i in range(10):
            self.svc.append_message(
                session.session_id,
                MessageRole.USER,
                f"Import benchmark message {i}",
            )
            self.db_session.commit()
        self.export_data = self.svc.export_session(session.session_id)

    def time_import_session(self):
        """Benchmark importing a session with 10 messages."""
        self.svc.import_session(self.export_data)
        self.db_session.commit()
