"""Factory runtime: one cycle hunts then assembles; re-running dedups (honest global trial count)."""
from __future__ import annotations

import numpy as np

from fxhnt.adapters.persistence import DuckDbAnalyticalStore, SqlStrategyStore
from fxhnt.application import FactoryRuntime, Territory
from fxhnt.config import Settings
from fxhnt.domain.factory import StrategyStatus
from fxhnt.domain.models import AssetClass, Market, PriceSeries


class FakeData:
    name = "fake"

    def fetch(self, market: Market, start=None, end=None) -> PriceSeries:
        rng = np.random.default_rng(sum(ord(c) for c in market.symbol))
        close = 100.0 * np.cumprod(1.0 + rng.normal(0.001, 0.01, 1600))
        return PriceSeries(market=market, dates=tuple(str(i) for i in range(1600)), close=close)


def test_cycle_hunts_assembles_and_dedups(tmp_path) -> None:
    settings = Settings(analytical_path=str(tmp_path / "an.duckdb"), operational_dsn=f"sqlite:///{tmp_path / 'r.db'}")
    store = SqlStrategyStore(settings.operational_dsn)
    territories = [Territory(name="trend-hunter", kind="trend", markets=["AAA", "BBB"],
                             asset_class=AssetClass.FUTURE, param_grid=[{"window": 100.0}])]
    rt = FactoryRuntime(FakeData(), DuckDbAnalyticalStore(settings.analytical_path), store, settings,
                        territory_provider=lambda: territories, book_status=StrategyStatus.DISCOVERED)

    c1 = rt.cycle()
    assert c1.fleet.candidates_tested == 2 and c1.fleet.global_trials == 2
    assert c1.fleet.specialists_found >= 1
    assert isinstance(c1.book.target_weights, dict)        # a book was assembled

    c2 = rt.cycle()                                        # re-run: everything already seen
    assert c2.fleet.candidates_tested == 0                 # dedup — no re-testing
    assert c2.fleet.global_trials == 2                     # global count stays honest
