#!/usr/bin/env python3
"""
Run research steps 1–7 in sequence and append stdout to a log file.

 1–2 + 7: vrp_research_metrics.py (metrics, R1 digest, VVIX quartiles)
 3–4:     vrp_research_sweeps.py (slippage + walk-forward)
 5:       vrp_research_theta_vs_ivol.py (skipped if --parquet missing)
 6:       vrp_research_overfit_notes.py (checklist text)

Usage::

    python RenTech/strategy_stack/vrp_research_run_1_7.py --start 2020-01-01 --end 2023-12-31
    python RenTech/strategy_stack/vrp_research_run_1_7.py --log RenTech/data/logs/vrp_steps_1_7.log
"""

from __future__ import annotations

import argparse
import os
import subprocess
import sys
from pathlib import Path
from textwrap import dedent

_REPO_ROOT = Path(__file__).resolve().parents[2]
_SCR = _REPO_ROOT / "RenTech" / "strategy_stack"
_DEFAULT_LOG = _REPO_ROOT / "RenTech" / "data" / "logs" / "vrp_research_steps_1_7.log"
_DEFAULT_IV = _REPO_ROOT / "SPY-Option-Data" / "spy_options_eod_combined.parquet"


def main() -> None:
    ap = argparse.ArgumentParser(description="Run VRP research steps 1–7 and log output")
    ap.add_argument("--theta-dir", type=Path, default=None)
    ap.add_argument("--parquet", type=Path, default=_DEFAULT_IV)
    ap.add_argument("--capital", type=float, default=None)
    ap.add_argument("--start", type=str, default="2020-01-01")
    ap.add_argument("--end", type=str, default="2023-12-31")
    ap.add_argument("--max-days", type=int, default=0)
    ap.add_argument("--no-progress", action="store_true")
    ap.add_argument("--log", type=Path, default=_DEFAULT_LOG)
    ap.add_argument("--skip-theta-ivol", action="store_true", help="Do not run step 5")
    args = ap.parse_args()

    py = sys.executable
    cap = [] if args.capital is None else ["--capital", str(args.capital)]
    common = [
        "--start",
        args.start,
        "--end",
        args.end,
        *(["--max-days", str(args.max_days)] if int(args.max_days) > 0 else []),
        *(["--no-progress"] if args.no_progress else []),
    ]
    td = [] if args.theta_dir is None else ["--theta-dir", str(args.theta_dir)]

    steps: list[tuple[str, list[str]]] = [
        ("metrics", [str(_SCR / "vrp_research_metrics.py"), *td, *cap, *common]),
        ("sweeps", [str(_SCR / "vrp_research_sweeps.py"), *td, *cap, *common]),
        ("overfit_notes", [str(_SCR / "vrp_research_overfit_notes.py")]),
    ]
    if not args.skip_theta_ivol and args.parquet.expanduser().is_file():
        steps.insert(
            2,
            (
                "theta_vs_ivol",
                [
                    str(_SCR / "vrp_research_theta_vs_ivol.py"),
                    *td,
                    "--parquet",
                    str(args.parquet),
                    *cap,
                    *common,
                ],
            ),
        )
    elif not args.skip_theta_ivol:
        msg = f"Step 5 SKIPPED: Parquet not found: {args.parquet}"
        steps.insert(2, ("theta_vs_ivol", [py, "-c", f"print({msg!r})"]))

    args.log.parent.mkdir(parents=True, exist_ok=True)
    banner = dedent(
        f"""
        {'=' * 72}
        VRP research run 1–7
        start={args.start} end={args.end} max_days={args.max_days}
        log={args.log}
        {'=' * 72}
        """
    )
    args.log.write_text(banner, encoding="utf-8")

    env = {**os.environ, "PYTHONUNBUFFERED": "1"}
    for name, cmd in steps:
        if cmd[0].endswith(".py"):
            full_cmd = [py, *cmd]
        else:
            full_cmd = cmd
        block = f"\n\n### --- {name} ---\n"
        with args.log.open("a", encoding="utf-8") as logf:
            logf.write(block)
            logf.flush()
            p = subprocess.run(full_cmd, cwd=str(_REPO_ROOT), env=env, capture_output=True, text=True)
            logf.write(p.stdout)
            if p.stderr:
                logf.write("\n--- stderr ---\n")
                logf.write(p.stderr)
            logf.write(f"\n[exit code {p.returncode}]\n")
        print(block + p.stdout[:2000] + ("..." if len(p.stdout) > 2000 else ""))
        if p.returncode != 0:
            print(f"ERROR: step {name} failed with code {p.returncode}", file=sys.stderr)
            sys.exit(p.returncode)

    print(f"\nFull log: {args.log}")


if __name__ == "__main__":
    main()
