#!/usr/bin/env python3
"""Root orchestration entry point; preparation scripts remain owned by their authors."""
from __future__ import annotations
import argparse, subprocess, sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]

def run_visualize() -> None:
    script = ROOT / "전처리/visualize_processed.py"
    if not script.exists():
        raise SystemExit("Visualization generator is not available yet: 전처리/visualize_processed.py")
    subprocess.run([sys.executable, str(script), "--help"], cwd=ROOT, check=True)
    subprocess.run([sys.executable, str(script)], cwd=ROOT, check=True)

def run_match_targets() -> None:
    subprocess.run([sys.executable, str(ROOT / "전처리/match_targets.py")], cwd=ROOT, check=True)

def run_weak_gnn() -> None:
    subprocess.run([
        sys.executable, "-m", "models.train_weak_gnn",
        "--allow-diagnostic-weak-labels", "--epochs", "400", "--learning-rate", "0.003",
    ], cwd=ROOT, check=True)

def run_model_dashboard() -> None:
    subprocess.run([sys.executable, "-m", "models.build_dashboard"], cwd=ROOT, check=True)

def run_cad_prediction_comparison() -> None:
    subprocess.run([sys.executable, "-m", "models.compare_cad_predictions"], cwd=ROOT, check=True)
    run_model_dashboard()

def run_attributions() -> None:
    subprocess.run([sys.executable, "-m", "models.attributions", "--build"], cwd=ROOT, check=True)
    run_model_dashboard()

def run_prepare() -> None:
    scripts = [ROOT / "전처리/cad_graphs.py", ROOT / "전처리/brep.py", ROOT / "전처리/representations.py"]
    missing = [str(x.relative_to(ROOT)) for x in scripts if not x.exists()]
    if missing: raise SystemExit("Preparation scripts are not available yet: " + ", ".join(missing))
    for script in scripts:
        # Help must succeed before invoking a separately-owned CLI.
        subprocess.run([sys.executable, str(script), "--help"], cwd=ROOT, check=True)
        subprocess.run([sys.executable, str(script)], cwd=ROOT, check=True)
    run_match_targets()
    run_visualize()

def main() -> None:
    p = argparse.ArgumentParser(description="Prepare representations and run label-gated POC baselines")
    p.add_argument("--prepare", action="store_true", help="run graph, B-Rep, and representation preparation CLIs")
    p.add_argument("--smoke", action="store_true", help="run actual-input architecture forward smoke tests")
    p.add_argument("--visualize", action="store_true", help="rebuild processed-data galleries without preparation or model execution")
    p.add_argument("--match-targets", action="store_true", help="match STEP/XLS to fused PLY and defect CSV, then rebuild galleries")
    p.add_argument("--train-weak-gnn", action="store_true", help="explicitly run the two-sample weak-label GNN training diagnostic")
    p.add_argument("--model-dashboard", action="store_true", help="build the model input/fusion/result web dashboard")
    p.add_argument("--compare-cad-predictions", action="store_true", help="fit weak diagnostics and map every model output to common CAD nodes")
    p.add_argument("--attributions", action="store_true", help="write prepared-sample local input-response diagnostics")
    p.add_argument("--all", action="store_true", help="prepare then forward smoke plus synthetic-only GP/BO demo")
    p.add_argument("--train", type=Path, help="external validated NPZ contract passed to models.runner")
    args = p.parse_args()
    if not any((args.prepare,args.smoke,args.visualize,args.match_targets,args.train_weak_gnn,args.model_dashboard,args.compare_cad_predictions,args.attributions,args.all,args.train)): p.error("choose --prepare, --visualize, --match-targets, --train-weak-gnn, --model-dashboard, --compare-cad-predictions, --attributions, --smoke, --all, or --train")
    if args.prepare or args.all: run_prepare()
    elif args.visualize: run_visualize()
    elif args.match_targets:
        run_match_targets(); run_visualize()
    if args.train_weak_gnn:
        run_weak_gnn()
    if args.model_dashboard:
        run_model_dashboard()
    if args.compare_cad_predictions:
        run_cad_prediction_comparison()
    if args.attributions:
        run_attributions()
    if args.smoke or args.all or args.train:
        cmd = [sys.executable, "-m", "models.runner"]
        if args.all: cmd.append("--all")
        elif args.smoke: cmd.append("--smoke")
        if args.train: cmd += ["--train", str(args.train)]
        subprocess.run(cmd, cwd=ROOT, check=True)

if __name__ == "__main__": main()
