from __future__ import annotations

import json

from src.tools.v77_signal_funnel import build_signal_funnel


def _append(path, row):
    with path.open("a", encoding="utf-8") as handle:
        handle.write(json.dumps(row) + "\n")


def test_signal_funnel_deduplicates_windows_and_quantifies_gate_families(tmp_path):
    runtime = tmp_path / "candidate"
    runtime.mkdir()
    journal = runtime / "signal_journal.jsonl"
    base = {"strategy_id": "candidate", "strategy_version": "v77.1.0", "coin": "ETH", "data_window_id": "w1", "timestamp": "2026-07-11T10:00:00+00:00", "would_enter": False}
    _append(journal, {**base, "block_reason": ["confluence_block_new_entry"]})
    _append(journal, {**base, "timestamp": "2026-07-11T10:00:01+00:00", "block_reason": ["confluence_block_new_entry", "confluence_event_risk_red"]})
    _append(journal, {**base, "coin": "LINK", "data_window_id": "w2", "block_reason": ["coingecko_source_unreliable_or_stale"]})
    _append(journal, {**base, "coin": "BTC", "data_window_id": "w3", "block_reason": ["no_confirmed_close_reclaim", "confluence_block_new_entry"]})
    report = build_signal_funnel(runtime, strategy_version="v77.1.0")
    assert report["unique_coin_windows"] == 3
    assert report["raw_rows"] == 4
    assert report["would_pass_without_confluence"] == 1
    assert report["would_pass_without_external_freshness"] == 1
    assert report["core_signal_blocked"] == 1
    assert report["gate_families"]["confluence"] == 2
    assert report["execution_allowed"] is False
    assert report["live_order_allowed"] is False


def test_signal_funnel_excludes_other_strategy_versions_and_invalid_rows(tmp_path):
    runtime = tmp_path / "candidate"
    runtime.mkdir()
    journal = runtime / "signal_journal.jsonl"
    _append(journal, {"strategy_version": "legacy", "coin": "ETH", "data_window_id": "x", "block_reason": []})
    with journal.open("a", encoding="utf-8") as handle:
        handle.write("{broken\n")
    report = build_signal_funnel(runtime, strategy_version="v77.1.0")
    assert report["unique_coin_windows"] == 0
    assert report["invalid_rows"] == 1
