"""Helpers for reading effective baked sleeves from experiment manifests."""
from __future__ import annotations

import json
from pathlib import Path
from typing import Any

_TOP_LEVEL_KEYS = {
    "idle_alpha_sleeve_preset": "idle_alpha",
    "form4_capture_sleeve_preset": "form4_sleeve",
    "ownership_capture_sleeve_preset": "ownership_sleeve",
    "risk_off_alpha_sleeve_preset": "risk_off_sleeve",
}


def _empty_baked_sleeves() -> dict[str, str | None]:
    return {
        "parking": None,
        "idle_alpha": None,
        "form4_sleeve": None,
        "ownership_sleeve": None,
        "risk_off_sleeve": None,
    }


def _apply_payload_baked_sleeves(target: dict[str, str | None], payload: dict[str, Any]) -> None:
    risk = payload.get("risk")
    if isinstance(risk, dict) and "cash_parking_preset" in risk:
        target["parking"] = risk.get("cash_parking_preset")
    for src_key, dst_key in _TOP_LEVEL_KEYS.items():
        if src_key in payload:
            target[dst_key] = payload.get(src_key)

    overrides = payload.get("overrides")
    if not isinstance(overrides, dict):
        return

    ov_risk = overrides.get("risk")
    if isinstance(ov_risk, dict) and "cash_parking_preset" in ov_risk:
        target["parking"] = ov_risk.get("cash_parking_preset")
    for src_key, dst_key in _TOP_LEVEL_KEYS.items():
        if src_key in overrides:
            target[dst_key] = overrides.get(src_key)


def _resolve_base_config_path(base_ref: str, config_path: Path, project_root: Path) -> Path | None:
    candidate = Path(base_ref)
    if candidate.is_absolute():
        return candidate if candidate.exists() else None

    for path in (config_path.parent / candidate, project_root / candidate):
        if path.exists():
            return path
    return None


def _read_recursive(
    config_path: Path,
    project_root: Path,
    visited: set[Path],
    depth_left: int,
) -> dict[str, str | None]:
    baked = _empty_baked_sleeves()
    if depth_left < 0 or not config_path.exists():
        return baked

    resolved_path = config_path.resolve()
    if resolved_path in visited:
        return baked
    visited.add(resolved_path)

    try:
        payload = json.loads(config_path.read_text())
    except Exception:
        return baked
    if not isinstance(payload, dict):
        return baked

    base_ref = payload.get("base_config")
    if isinstance(base_ref, str) and base_ref:
        base_path = _resolve_base_config_path(base_ref, config_path, project_root)
        if base_path is not None:
            baked = _read_recursive(base_path, project_root, visited, depth_left - 1)

    # Current payload wins. Explicit nulls are meaningful because they clear inherited sleeves.
    _apply_payload_baked_sleeves(baked, payload)
    return baked


def read_effective_baked_sleeves(
    config_path: Path,
    project_root: Path,
    max_depth: int = 8,
) -> dict[str, str | None]:
    """Resolve effective baked sleeves from a manifest/base_config chain."""
    try:
        return _read_recursive(config_path, project_root, visited=set(), depth_left=max_depth)
    except Exception:
        return _empty_baked_sleeves()
