"""Persistence contracts. Stores by purpose (per the chosen Postgres + DuckDB split):
  * OperationalRepository — relational (Postgres/SQLite): research runs, verdicts, survivor library.
  * AnalyticalStore       — columnar (DuckDB): market price series + backtest return timeseries.
  * StrategyStore         — relational: the factory's strategy-lifecycle population + global trial counter.
"""
from __future__ import annotations

from typing import Protocol

import numpy as np

from fxhnt.domain.factory import StrategyRecord, StrategyStatus
from fxhnt.domain.models import Market, PriceSeries, ResearchRun


class OperationalRepository(Protocol):
    def save_run(self, run: ResearchRun) -> None: ...

    def get_run(self, run_id: str) -> ResearchRun | None: ...

    def list_runs(self, *, passed_only: bool = False) -> list[ResearchRun]: ...


class AnalyticalStore(Protocol):
    def save_prices(self, prices: PriceSeries) -> None: ...

    def load_prices(self, market: Market) -> PriceSeries | None: ...

    def save_returns(self, run_id: str, dates: tuple[str, ...], returns: np.ndarray) -> None: ...


class StrategyStore(Protocol):
    def upsert(self, record: StrategyRecord) -> None: ...

    def get(self, strategy_id: str) -> StrategyRecord | None: ...

    def list(self, *, status: StrategyStatus | None = None, regime: str | None = None) -> list[StrategyRecord]: ...

    def set_status(self, strategy_id: str, status: StrategyStatus) -> None: ...

    def add_trials(self, n: int) -> None: ...   # increment the global hypothesis count (honesty-at-scale)

    def total_trials(self) -> int: ...

    def is_seen(self, key: str) -> bool: ...     # has this exact candidate been tested before?

    def mark_seen(self, key: str) -> None: ...   # record a candidate as tested (distinct-hypothesis dedup)
