"""Thread-safe in-memory storage for API coverage analysis sessions."""

import threading
from dataclasses import dataclass, field
from uuid import uuid4


@dataclass
class CoverageSession:
    """Active session for the check_api_coverage tool."""

    session_id: str
    target_path: str
    base_for_rel: str
    file_list: list[str]
    status: str = "scanning"  # "scanning" | "completed"
    derived_apis: list[dict] = field(default_factory=list)
    derived_flows: list[dict] = field(default_factory=list)
    api_fingerprints: set[str] = field(default_factory=set)
    flow_fingerprints: set[str] = field(default_factory=set)


class CoverageStore:
    """Thread-safe storage for API coverage analysis sessions."""

    def __init__(self) -> None:
        self._lock = threading.RLock()
        self._sessions: dict[str, CoverageSession] = {}

    def create_session(
        self,
        target_path: str,
        base_for_rel: str,
        file_list: list[str],
    ) -> str:
        """Create a new coverage session and return its session_id."""
        with self._lock:
            session_id = str(uuid4())
            self._sessions[session_id] = CoverageSession(
                session_id=session_id,
                target_path=target_path,
                base_for_rel=base_for_rel,
                file_list=file_list,
            )
            return session_id

    def get_session(self, session_id: str) -> CoverageSession | None:
        """Retrieve a session by ID."""
        with self._lock:
            return self._sessions.get(session_id)

    def add_derived(
        self,
        session_id: str,
        apis: list[dict],
        flows: list[dict],
    ) -> None:
        """Add derived APIs and flows, deduplicating by fingerprint."""
        with self._lock:
            session = self._sessions.get(session_id)
            if not session:
                return
            for api in apis:
                fp = f"{(api.get('method') or '').upper()}|{api.get('endpoint') or ''}"
                if fp not in session.api_fingerprints:
                    session.api_fingerprints.add(fp)
                    session.derived_apis.append(api)
            for flow in flows:
                fp = (flow.get("name") or "").lower().strip()
                if fp and fp not in session.flow_fingerprints:
                    session.flow_fingerprints.add(fp)
                    session.derived_flows.append(flow)

    def mark_completed(self, session_id: str) -> None:
        """Mark session as completed."""
        with self._lock:
            session = self._sessions.get(session_id)
            if session:
                session.status = "completed"
