"""Port defining how the application accesses test data.

This is a domain contract — implementations live in infrastructure/.
"""

from __future__ import annotations

import uuid
from typing import Protocol, runtime_checkable

from app.domain.enums import TestState


class TestRepository(Protocol):
    """Data access contract for tests."""

    # -- Single-entity access ----------------------------------------------

    def find_by_id(self, test_id: uuid.UUID) -> object | None:
        """Return a Test ORM model by primary key, or None.

        Returns the ORM model directly (not a domain entity) because
        the TestEntity is constructed at the service layer via
        ``TestEntity.from_orm()``.
        """
        ...

    # -- List access -------------------------------------------------------

    def list_by_technique(self, technique_id: uuid.UUID) -> list[object]: ...

    def list_by_state(self, state: TestState) -> list[object]: ...

    def count_by_technique_and_state(
        self,
        technique_id: uuid.UUID,
    ) -> dict[TestState, int]:
        """Return test counts grouped by state for a single technique."""
        ...

    # -- Batch queries -----------------------------------------------------

    def get_states_and_results_for_technique(
        self,
        technique_id: uuid.UUID,
    ) -> list[tuple[str, str | None]]:
        """Return (state, detection_result) pairs for all tests of a technique.

        Used by TechniqueEntity.recalculate_status() without loading full
        test models.
        """
        ...
