#!/usr/bin/env python
"""
V3 cross-validation runner.

Outer/inner k-fold: test = current fold, val = next fold, train = rest.
No holdout. No checkpoint saving.

Usage (single fold-seed, 5-fold, binary, ensemble):
  python -m v3.scripts.main.run_cv \
      --run-name my_run \
      --eval-mode binary \
      --hypertower-mode ensemble \
      --epochs 40 \
      --augment \
      --tune-binary-threshold \
      --in-memory-cache

Usage (10x5 rep-CV, seeds 100..1000):
  python -m v3.scripts.main.run_cv \
      --run-name my_run_10x5 \
      --reps 10 \
      --rep-seed-start 100 \
      --rep-seed-step 100 \
      --eval-mode binary \
      --hypertower-mode ensemble \
      --epochs 40 \
      --augment \
      --tune-binary-threshold \
      --in-memory-cache
"""
import argparse
import sys
from pathlib import Path

# Allow running as `python v3/scripts/main/run_cv.py` from repo root
sys.path.insert(0, str(Path(__file__).resolve().parents[3]))

from v3.classes.v3_hypertower import V3HyperTower


def build_parser() -> argparse.ArgumentParser:
    ap = V3HyperTower.build_parser()
    ap.description = __doc__
    ap.formatter_class = argparse.RawDescriptionHelpFormatter
    ap.add_argument(
        "--reps", type=int, default=1,
        help="Number of repetitions (each rep uses a different --fold-seed).",
    )
    ap.add_argument(
        "--rep-seed-start", type=int, default=100,
        help="fold-seed for rep 0 (default: 100).",
    )
    ap.add_argument(
        "--rep-seed-step", type=int, default=100,
        help="Increment between rep fold-seeds (default: 100; rep k uses seed start + k*step).",
    )
    ap.add_argument(
        "--rep-index", type=int, default=None,
        help="Override the rep directory index (e.g. 3 → rep03). "
             "Used by the distributed server to run a single rep of a multi-rep job.",
    )
    return ap


def main():
    ap = build_parser()
    args = ap.parse_args()

    reps           = int(args.reps)
    seed_start     = int(args.rep_seed_start)
    seed_step      = int(args.rep_seed_step)
    base_run_name  = args.run_name or "v3_cv"
    rep_index_override = getattr(args, "rep_index", None)

    for rep in range(reps):
        rep_seed = seed_start + rep * seed_step
        args.fold_seed = rep_seed

        dir_index = rep_index_override if (rep_index_override is not None and reps == 1) else rep
        if reps > 1 or rep_index_override is not None:
            args.run_name = f"{base_run_name}/rep{dir_index:02d}"
            print(f"\n{'='*60}", flush=True)
            print(f"Rep {dir_index+1}  fold_seed={rep_seed}", flush=True)
            print(f"{'='*60}", flush=True)
        else:
            args.run_name = base_run_name

        tower = V3HyperTower(args)
        out_dir = tower.run()
        print(f"\nRep {dir_index+1} output: {out_dir}", flush=True)


if __name__ == "__main__":
    main()
