"""Factory runtime — one cycle of the standing research force: hunt for new regime-specialists, then
assemble today's regime-adaptive book from the active ones. Invoked on a schedule (cron), that recurrence
IS the 'constantly seeking' force; or looped in the foreground as a daemon. Distinct-hypothesis dedup in
the fleet keeps the global trial count honest across cycles."""
from __future__ import annotations

from collections.abc import Callable

from pydantic import BaseModel

from fxhnt.application.fleet import FleetOrchestrator, FleetReport, Territory
from fxhnt.application.regime_execution import RegimeBook, RegimeConditionalExecutor
from fxhnt.config import Settings
from fxhnt.domain.factory import StrategyStatus
from fxhnt.ports.data import DataProvider
from fxhnt.ports.repository import AnalyticalStore, StrategyStore


class CycleReport(BaseModel):
    fleet: FleetReport
    book: RegimeBook


class FactoryRuntime:
    def __init__(self, data: DataProvider, analytical: AnalyticalStore, store: StrategyStore, settings: Settings,
                 *, territory_provider: Callable[[], list[Territory]],
                 book_status: StrategyStatus = StrategyStatus.DEPLOYED, max_gross: float = 1.0) -> None:
        self._fleet = FleetOrchestrator(data, analytical, store, settings)
        self._exec = RegimeConditionalExecutor(data, analytical, store, settings)
        self._territory_provider = territory_provider   # called each cycle: fixed grids OR an agent's proposals
        self._book_status = book_status
        self._max_gross = max_gross

    def cycle(self) -> CycleReport:
        fleet = self._fleet.hunt(self._territory_provider())
        book = self._exec.assemble(status=self._book_status, max_gross_leverage=self._max_gross)
        return CycleReport(fleet=fleet, book=book)
