"""ASV benchmarks for async resource cleanup overhead (#321).

Measures registration, close_all, and leak-warning latency to establish
baselines for the AsyncResourceTracker.
"""

from __future__ import annotations

import asyncio

from cleveragents.core.async_cleanup import AsyncResourceTracker


class _FakeResource:
    """Minimal async resource for benchmarking."""

    def __init__(self) -> None:
        self.closed = False

    async def close(self) -> None:
        self.closed = True


def _make_tracker(count: int) -> AsyncResourceTracker:
    """Create a tracker pre-loaded with *count* fake resources."""
    tracker = AsyncResourceTracker()
    for i in range(count):
        tracker.register(f"res-{i}", _FakeResource())
    return tracker


class TimeRegisterSingle:
    """Benchmark registering a single resource."""

    timeout = 10

    def setup(self) -> None:
        self.tracker = AsyncResourceTracker()
        self.counter = 0

    def teardown(self) -> None:
        pass

    def time_register_one(self) -> None:
        name = f"bench-{self.counter}"
        self.counter += 1
        self.tracker.register(name, _FakeResource())


class TimeRegisterBatch:
    """Benchmark registering 100 resources in sequence."""

    timeout = 10
    number = 1  # Tracker cannot re-register names; recreate each iteration.

    def setup(self) -> None:
        self.tracker = AsyncResourceTracker()

    def teardown(self) -> None:
        pass

    def time_register_100(self) -> None:
        tracker = AsyncResourceTracker()
        for i in range(100):
            tracker.register(f"batch-{i}", _FakeResource())


class TimeCloseAll:
    """Benchmark close_all on pre-loaded trackers."""

    timeout = 30
    number = 1  # Re-create tracker for each iteration.

    def setup(self) -> None:
        self.tracker = _make_tracker(50)

    def teardown(self) -> None:
        pass

    def time_close_50_resources(self) -> None:
        asyncio.run(self.tracker.close_all())


class TimeCloseAllLarge:
    """Benchmark close_all with 500 resources."""

    timeout = 60
    number = 1

    def setup(self) -> None:
        self.tracker = _make_tracker(500)

    def teardown(self) -> None:
        pass

    def time_close_500_resources(self) -> None:
        asyncio.run(self.tracker.close_all())


class TimeLeakWarning:
    """Benchmark the _warn_unclosed finalizer path."""

    timeout = 10

    def setup(self) -> None:
        self.tracker = _make_tracker(20)

    def teardown(self) -> None:
        pass

    def time_warn_20_unclosed(self) -> None:
        self.tracker._warn_unclosed()


class TimeOpenCount:
    """Benchmark the open_count property."""

    timeout = 10

    def setup(self) -> None:
        self.tracker = _make_tracker(100)

    def teardown(self) -> None:
        pass

    def time_open_count(self) -> None:
        _ = self.tracker.open_count
