from __future__ import annotations

import json
import math
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from harness.gate_row20_cosmology import gate_cosmo
from harness.gate_row20_h0_resolution import gate_h0_resolution


def find_part(row20: dict, tag: str) -> dict:
    for part in row20.get("parts", []):
        if part.get("tag") == tag:
            return part
    return {}


def composite_h0_release_test(dataset_dir: str = "datasets") -> dict:
    row20 = gate_cosmo(dataset_dir)
    h0_gate = gate_h0_resolution(dataset_dir)

    h0_early = float(h0_gate["summary"]["h0_early_anchor"])
    h0_local = float(h0_gate["summary"]["h0_local_target"])
    h0_needed = h0_local - h0_early

    bao_shift = float(h0_gate["summary"]["delta_h0_from_bao_bridge"])

    cosmo_meta = row20.get("summary", {}).get("cosmo_meta", {})
    cmb_calibration = float(cosmo_meta.get("cmb_calibration", 1.0))
    cmb_shift = h0_early * (cmb_calibration - 1.0)

    gw = find_part(row20, "GW")
    gw_residual_preview = gw.get("residual_preview", [])
    gw_shift = float(gw_residual_preview[0]) if gw_residual_preview else 0.0

    raw_composite_shift = bao_shift + cmb_shift + gw_shift
    raw_composite_h0 = h0_early + raw_composite_shift
    raw_remaining_gap = h0_local - raw_composite_h0

    # Conservative coherence test:
    # Require that all three pieces point upward and are already present in v22.
    pieces = {
        "BAO": {
            "shift": bao_shift,
            "source": "BAO_DM_H covariance bridge",
            "validity": "VALID_EXISTING_BRIDGE",
        },
        "CMB": {
            "shift": cmb_shift,
            "source": "cmb_calibration from cosmology meta",
            "validity": "PROXY_REQUIRES_DERIVATION",
        },
        "GW": {
            "shift": gw_shift,
            "source": "GW residual proxy",
            "validity": "PROXY_REQUIRES_DERIVATION",
        },
    }

    all_present = (
        bao_shift > 0.0
        and cmb_shift > 0.0
        and gw_shift > 0.0
    )

    within_local_tolerance = abs(raw_composite_h0 - h0_local) <= 1.5

    no_fitted_weights = True
    no_new_parameters = True
    no_dataset_changes = True
    no_threshold_changes = True

    if all_present and within_local_tolerance:
        verdict = "CANDIDATE"
        status = "DISTRIBUTED_H0_RELEASE_CANDIDATE"
    elif all_present:
        verdict = "PARTIAL"
        status = "DISTRIBUTED_H0_RELEASE_PARTIAL_BUT_INSUFFICIENT"
    else:
        verdict = "CANNOT_SOLVE"
        status = "NO_DISTRIBUTED_H0_RELEASE_FOUND"

    return {
        "test": "UTFANSWF_v22_H0_COMPOSITE_RELEASE_TEST",
        "row20_signature": row20.get("signature"),
        "h0_gate_signature": h0_gate.get("signature"),
        "summary": {
            "h0_early_anchor": h0_early,
            "h0_local_target": h0_local,
            "h0_needed_shift": h0_needed,
            "bao_bridge_shift": bao_shift,
            "cmb_calibration_shift": cmb_shift,
            "gw_proxy_shift": gw_shift,
            "raw_composite_shift": raw_composite_shift,
            "raw_composite_h0": raw_composite_h0,
            "raw_remaining_gap": raw_remaining_gap,
            "within_local_tolerance": within_local_tolerance,
            "status": status,
            "rules": {
                "no_fitted_weights": no_fitted_weights,
                "physics_changed": False,
                "thresholds_changed": not no_threshold_changes,
                "datasets_changed": not no_dataset_changes,
                "new_free_parameters": not no_new_parameters,
            },
        },
        "pieces": pieces,
        "interpretation": {
            "main_point": (
                "This test checks whether H0 release is distributed across already-existing "
                "v22 BAO, CMB, and GW outputs rather than sitting in a single mechanism."
            ),
            "warning": (
                "CMB and GW contributions are treated as proxies here. This is not a final "
                "H0 solution unless a derivation justifies combining them without double counting."
            ),
        },
        "verdict": verdict,
    }


if __name__ == "__main__":
    result = composite_h0_release_test("datasets")

    print("\n================================")
    print(f"H0 COMPOSITE RELEASE TEST — {result['verdict']}")
    print(f"status: {result['summary']['status']}")
    print(f"raw composite H0: {result['summary']['raw_composite_h0']:.6f}")
    print(f"remaining gap: {result['summary']['raw_remaining_gap']:.6f}")
    print("================================\n")

    print(json.dumps(result, indent=2))