#!/usr/bin/env python3
"""
Build a WSC (or WOB stub) from data using a declared context.

Inputs:
- system_config.json (declared context)
- optional loop phases file for degree inference
- optional two-cycle data CSV for target inference

Outputs:
- prints a JSON artifact (WSC or WOB stub) to stdout

This tool is conservative. If target inference is inconclusive, it emits WOB-06-coupling-mismatch
or WOB-09-equivariance-defect style stubs depending on the declared intent.
"""
import argparse, json, math, subprocess, tempfile
from pathlib import Path

def run(cmd):
    res = subprocess.run(cmd, capture_output=True, text=True)
    if res.returncode != 0:
        raise RuntimeError(res.stderr)
    return res.stdout.strip()

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--config", required=True)
    ap.add_argument("--loop_phases", default=None)
    ap.add_argument("--two_cycle_csv", default=None)
    ap.add_argument("--tol_frac", type=float, default=0.05)
    args = ap.parse_args()

    cfg = json.loads(Path(args.config).read_text(encoding="utf-8"))
    P = float(cfg.get("period_P", 2*math.pi))

    # Infer degree if phases provided
    if args.loop_phases is not None:
        k = int(run(["python3", str(Path(__file__).parent/"infer_degree_from_loop.py"),
                     "--period", str(P), "--phases", args.loop_phases]))
        cfg["k"] = k
        cfg.setdefault("witness_kind","degree")

    # Infer two-cycle target if csv provided
    if args.two_cycle_csv is not None:
        out = run(["python3", str(Path(__file__).parent/"infer_target_two_cycle.py"),
                   "--period", str(P), "--data", args.two_cycle_csv, "--tol", str(args.tol_frac)])
        inf = json.loads(out)
        if inf["target_type"] == "cst":
            cfg["target_type"] = "cst"
            cfg["target"] = "CST (inferred two-cycle coupling)"
            cfg.setdefault("assumptions", []).append("CTP/CHT (inferred CST target)")
        else:
            cfg["target_type"] = "torus"
            cfg["target"] = "T^2 (inferred uncoupled target)"

    # Use engine runner to produce artifact shape.
    # The runner must see any inferred fields (k, target_type, target, assumptions).
    runner = Path(__file__).parent.parent/"audit"/"engine_runner.py"

    with tempfile.TemporaryDirectory(prefix="sft_build_wsc_") as td:
        tmp_cfg = Path(td) / "system_config.inferred.json"
        tmp_cfg.write_text(json.dumps(cfg, indent=2) + "\n", encoding="utf-8")
        print(run(["python3", str(runner), str(tmp_cfg)]))

if __name__ == "__main__":
    main()
