"""Feature pipeline — the silver→gold transform. Streams normalized snapshots (in timestamp order, no
forward reads) through the stateful feature calculators and persists the point-in-time rows to the
warehouse. The transform is deterministic and causal: the same SSOT input always yields the same gold."""
from __future__ import annotations

from collections.abc import Iterable

from fxhnt.domain.features.base import SnapshotFeatureCalculator
from fxhnt.domain.marketdata import Mbp10Snapshot
from fxhnt.ports.warehouse import FeatureStore


class FeaturePipeline:
    def __init__(self, store: FeatureStore, calculators: list[SnapshotFeatureCalculator]) -> None:
        self._store = store
        self._calculators = calculators

    def process(self, symbol: str, snapshots: Iterable[Mbp10Snapshot]) -> int:
        """Run snapshots (which MUST be in ascending ts order) through every calculator and persist.
        Returns the number of rows written."""
        rows = []
        for snap in snapshots:
            features: dict[str, float] = {}
            for calc in self._calculators:
                features.update(calc.update(snap))
            rows.append((snap.ts, features))
        self._store.write_features(symbol, rows)
        return len(rows)
