"""ASV benchmarks for session create service-layer performance (bug #570).

Measures the cost of creating a session through ``PersistentSessionService``
using a file-based SQLite database so that each operation exercises the full
service layer (repository -> SQLAlchemy -> SQLite round-trip).

Note: these benchmarks construct ``PersistentSessionService`` directly and do
**not** exercise the DI container wiring path (``_get_session_service`` /
``container.db()``).  Their purpose is to establish a service-layer create
performance baseline so regressions can be detected after the bug-fix lands.
Same root cause as bug #554.
"""

from __future__ import annotations

import importlib
import os
import shutil
import sys
import tempfile
from pathlib import Path

_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
    sys.path.insert(0, _SRC)

import cleveragents  # noqa: E402

importlib.reload(cleveragents)

from sqlalchemy import create_engine  # noqa: E402
from sqlalchemy.orm import sessionmaker  # noqa: E402

from cleveragents.application.services.session_service import (  # noqa: E402
    PersistentSessionService,
)
from cleveragents.infrastructure.database.models import Base  # noqa: E402
from cleveragents.infrastructure.database.repositories import (  # noqa: E402
    SessionMessageRepository,
    SessionRepository,
)


class SessionCreateDISuite:
    """Benchmark session create through the service layer.

    Engine and sessionmaker are built once in ``setup()`` and reused across
    benchmark iterations to measure service-layer cost without engine
    construction overhead.
    """

    timeout = 60

    def setup(self) -> None:
        self._tmpdir = tempfile.mkdtemp(prefix="bench_sce_570_")
        self._db_path = os.path.join(self._tmpdir, "bench.db")
        self._engine = create_engine(f"sqlite:///{self._db_path}", echo=False)
        Base.metadata.create_all(self._engine)
        self._session_factory = sessionmaker(bind=self._engine, expire_on_commit=False)

    def teardown(self) -> None:
        self._engine.dispose()
        shutil.rmtree(self._tmpdir, ignore_errors=True)

    def _make_service(self) -> PersistentSessionService:
        """Build a PersistentSessionService using the shared session factory."""
        return PersistentSessionService(
            session_repo=SessionRepository(session_factory=self._session_factory),
            message_repo=SessionMessageRepository(
                session_factory=self._session_factory
            ),
        )

    def time_create_session(self) -> None:
        """Create a session via the service layer."""
        svc = self._make_service()
        svc.create()

    def time_create_with_actor(self) -> None:
        """Create a session with a custom actor."""
        svc = self._make_service()
        svc.create(actor_name="openai/gpt-4")

    def track_create_persists(self) -> int:
        """Track session create persistence at the service layer.

        Returns the count of sessions created via the service.  This
        benchmark constructs ``PersistentSessionService`` directly,
        bypassing the DI container (``_get_session_service`` /
        ``container.db()``).  It therefore does **not** reproduce bug
        #570 — its purpose is to establish a service-layer persistence
        baseline so regressions can be detected after the fix lands.
        """
        svc = self._make_service()
        svc.create(actor_name="bench/create-test")
        sessions = svc.list()
        return len(sessions)


SessionCreateDISuite.track_create_persists.unit = "sessions"
