"""SH01 path live: last_block_only == tail del walk-forward completo (parity by
construction) + merge storia parquet/feed del runner."""
import numpy as np
import pandas as pd
import pytest

from src.portfolio.runner import _with_history


def _df(n=6500, seed=0, t0=1_600_000_000_000):
    rng = np.random.default_rng(seed)
    c = 100 * np.exp(np.cumsum(rng.normal(0, 0.01, n)))
    h = c * (1 + np.abs(rng.normal(0, 0.004, n)))
    l = c * (1 - np.abs(rng.normal(0, 0.004, n)))
    o = np.roll(c, 1); o[0] = c[0]
    ts = t0 + 3_600_000 * np.arange(n)
    return pd.DataFrame({"timestamp": ts, "open": o, "high": h, "low": l,
                         "close": c, "volume": 1.0})


def test_last_block_only_matches_full_wf_tail():
    from scripts.analysis.shape_ml_research import ml_wf_entries
    df = _df()
    cfg = dict(W=24, H=12, model="logit", thresh=0.55, train_min=4000, retrain=500)
    full = ml_wf_entries(df, **cfg)
    last = ml_wf_entries(df, last_block_only=True, **cfg)
    n = len(df)
    # confine dell'ultimo blocco: start + k*retrain (deterministico)
    start = max(cfg["train_min"], cfg["W"] - 1)
    B = start
    while B + cfg["retrain"] < n - 1:
        B += cfg["retrain"]
    full_tail = [e for e in full if e["i"] >= B]
    assert last == full_tail                       # identita' esatta, non solo simile
    assert all(e["i"] >= B for e in last)


def test_with_history_merges_contiguous():
    hist = _df(n=100)
    live = _df(n=50, t0=int(hist["timestamp"].iloc[60]))   # overlap: live parte dentro hist
    out = _with_history(hist, live)
    assert len(out) == 60 + 50                      # hist pre-overlap + live completo
    ts = out["timestamp"].values
    assert (np.diff(ts) > 0).all()                  # serie strettamente crescente


def test_with_history_gap_falls_back_to_live():
    hist = _df(n=100)
    gap_start = int(hist["timestamp"].iloc[-1]) + 10 * 3_600_000   # buco di 10 barre
    live = _df(n=50, t0=gap_start)
    warned = set()
    out = _with_history(hist, live, warned, "BTC")
    assert len(out) == 50 and "BTC" in warned       # solo feed + warn deduplicato
    out2 = _with_history(hist, live, warned, "BTC")
    assert len(out2) == 50                          # secondo giro: nessun nuovo warn


def test_with_history_none_hist_passthrough():
    live = _df(n=50)
    assert _with_history(None, live) is live
