"""ASV benchmarks for project CLI command parsing overhead.

Measures the cost of:
- Creating a project via the domain model + repository
- Listing projects with namespace filter
- Generating the project spec dict for output formatting
"""

from __future__ import annotations

from typing import Any

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from cleveragents.domain.models.core.project import (
    NamespacedProject,
    parse_namespaced_name,
)
from cleveragents.infrastructure.database.models import Base
from cleveragents.infrastructure.database.repositories import (
    NamespacedProjectRepository,
)


class _NoCloseSession:
    """Session wrapper that no-ops close() for in-memory SQLite."""

    def __init__(self, real: object) -> None:
        object.__setattr__(self, "_real", real)

    def close(self) -> None:
        pass

    def __getattr__(self, name: str) -> Any:
        return getattr(object.__getattribute__(self, "_real"), name)


def _make_repo() -> NamespacedProjectRepository:
    engine = create_engine("sqlite:///:memory:", echo=False)
    Base.metadata.create_all(engine)
    sess = sessionmaker(bind=engine, expire_on_commit=False)()
    wrapper = _NoCloseSession(sess)
    return NamespacedProjectRepository(session_factory=lambda: wrapper)


class ProjectCreateBenchmark:
    """Benchmark project creation performance."""

    timeout = 30.0

    def setup(self) -> None:
        self.repo = _make_repo()
        self.counter = 0

    def time_create_project(self) -> None:
        self.counter += 1
        parsed = parse_namespaced_name(f"bench-{self.counter}")
        proj = NamespacedProject(
            name=parsed.name,
            namespace=parsed.namespace,
        )
        self.repo.create(proj)


class ProjectListBenchmark:
    """Benchmark project listing performance."""

    timeout = 30.0

    def setup(self) -> None:
        self.repo = _make_repo()
        for i in range(50):
            parsed = parse_namespaced_name(f"proj-{i}")
            proj = NamespacedProject(
                name=parsed.name,
                namespace=parsed.namespace,
            )
            self.repo.create(proj)

    def time_list_all(self) -> None:
        self.repo.list_projects()

    def time_list_filtered(self) -> None:
        self.repo.list_projects(namespace="local")


class ProjectSpecDictBenchmark:
    """Benchmark spec dict generation performance."""

    timeout = 30.0

    def setup(self) -> None:
        self.repo = _make_repo()
        parsed = parse_namespaced_name("bench-dict")
        proj = NamespacedProject(
            name=parsed.name,
            namespace=parsed.namespace,
            description="Benchmark project",
        )
        self.repo.create(proj)
        self.project = self.repo.get("local/bench-dict")

    def time_spec_dict(self) -> None:
        from cleveragents.cli.commands.project import _project_spec_dict

        _project_spec_dict(self.project)
