"""ASV benchmarks for project-scoped config resolution overhead.

Measures the performance impact of project-scoped resolution compared
to global-only resolution, including:
- Resolution with project scope active
- Resolution with project scope inactive (no project name)
- get_project_overrides() lookup
- set_project_value() write
"""

from __future__ import annotations

import importlib
import shutil
import sys
import tempfile
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)

import cleveragents  # noqa: E402

importlib.reload(cleveragents)

from cleveragents.application.services.config_service import (  # noqa: E402
    ConfigService,
)


class ProjectScopeResolutionTimeSuite:
    """Benchmark timing for project-scoped config resolution."""

    def setup(self) -> None:
        self._tmpdir = Path(tempfile.mkdtemp())
        self._service = ConfigService(
            config_dir=self._tmpdir,
            config_path=self._tmpdir / "config.toml",
        )
        # Pre-populate some project-scoped values
        self._service.set_project_value(
            "bench-project", "core.automation-profile", "trusted"
        )
        self._service.set_project_value("bench-project", "plan.concurrency", "16")

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

    def time_resolve_with_project_scope(self) -> None:
        """Resolve a key with project scope active (project override exists)."""
        self._service.resolve("core.automation-profile", project_name="bench-project")

    def time_resolve_without_project_scope(self) -> None:
        """Resolve a key without project scope (baseline)."""
        self._service.resolve("core.automation-profile")

    def time_resolve_project_scope_no_override(self) -> None:
        """Resolve a key with project scope but no override for that key."""
        self._service.resolve("core.log.level", project_name="bench-project")

    def time_get_project_overrides(self) -> None:
        """Look up all overrides for a project."""
        self._service.get_project_overrides("bench-project")

    def time_set_project_value(self) -> None:
        """Write a project-scoped value."""
        self._service.set_project_value("bench-project", "plan.concurrency", "32")

    def time_resolve_all_with_project(self) -> None:
        """Resolve all keys with a project name active."""
        self._service.resolve_all(project_name="bench-project")


class ProjectScopeResolutionMemSuite:
    """Benchmark memory consumption for project-scoped operations."""

    def setup(self) -> None:
        self._tmpdir = Path(tempfile.mkdtemp())
        self._service = ConfigService(
            config_dir=self._tmpdir,
            config_path=self._tmpdir / "config.toml",
        )
        self._service.set_project_value(
            "bench-project", "core.automation-profile", "trusted"
        )
        self._service.set_project_value("bench-project", "plan.concurrency", "16")

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

    def mem_resolve_all_with_project(self) -> dict:
        """Memory for resolving all keys with project scope."""
        return self._service.resolve_all(project_name="bench-project")

    def mem_get_project_overrides(self) -> dict:
        """Memory for get_project_overrides."""
        return self._service.get_project_overrides("bench-project")
