#!/usr/bin/env python3
"""
SFT Engine Runner (Template Generator)

This is a lightweight, reproducible entrypoint:

- reads a small config JSON describing a system context
- outputs either a WSC template (with stability_modulus filled where possible)
  or a WOB stub with correct code and evidence fields.

It does not claim to "solve physics"; it produces the correct *artifact shape*
and enforces target correctness and field consistency.
"""
import json, sys, math
from pathlib import Path

def fail(msg):
    print("FAIL:", msg)
    sys.exit(1)

def main():
    if len(sys.argv) != 2:
        fail("Usage: engine_runner.py path/to/system_config.json")

    cfg_path = Path(sys.argv[1])
    if not cfg_path.exists():
        fail(f"Config not found: {cfg_path}")
    cfg = json.loads(cfg_path.read_text(encoding="utf-8"))

    mode = cfg.get("mode", "wsc")  # wsc or wob
    sft_version = cfg.get("sft_version", "SFT-0.1.0")
    P = float(cfg.get("period_P", 2*math.pi))

    tier = cfg.get("witness_tier", "WTR-E")
    mechanism = cfg.get("mechanism", "LDW")
    target_type = cfg.get("target_type", "circle")  # circle, torus, cst
    target = cfg.get("target", "T_P")
    baseline = cfg.get("baseline", "Haar on the correct target")

    if mode == "wob":
        wob = {
            "sft_version": sft_version,
            "obstruction_id": cfg.get("obstruction_id", "WOB-TEMPLATE-0001"),
            "witness_tier": tier,
            "obstruction_code": cfg.get("obstruction_code", "WOB-01-no-subsystem"),
            "description": cfg.get("description", "Obstruction stub produced by engine runner."),
            "evidence": cfg.get("evidence", ["Add evidence bullet(s) here."]),
            "recommended_next_moves": cfg.get("recommended_next_moves", ["Add next-move bullet(s) here."])
        }
        print(json.dumps(wob, indent=2))
        return

    # default: WSC template
    k = int(cfg.get("k", 1))
    margins = cfg.get("margins", {"LCM_pi": 1.0})
    assumptions = cfg.get("assumptions", [])
    perturb = cfg.get("perturbation_model", "PM-2-lift-sup")

    wsc = {
        "sft_version": sft_version,
        "certificate_id": cfg.get("certificate_id", "WSC-TEMPLATE-0001"),
        "witness_tier": tier,
        "mechanism": mechanism,
        "target": target,
        "period_P": P,
        "witness_value": {
            "kind": cfg.get("witness_kind", "degree"),
            "integer": k,
            "notes": cfg.get("witness_notes", "")
        },
        "perturbation_model": perturb,
        "margins": margins,
        "assumptions": assumptions,
        "artifacts": {
            "theorem_refs": cfg.get("theorem_refs", []),
            "files": cfg.get("files", ["engine/schemas/witness_stability_certificate_schema.json","engine/audit/audit_wsc.py"])
        }
    }

    sm = {
        "k": k,
        "target_rank": int(cfg.get("target_rank", 1))
    }
    if "LCM_pi" in margins:
        sm["LCM_pi"] = float(margins["LCM_pi"])
    if "HMR_P" in margins:
        sm["HMR_P"] = float(margins["HMR_P"])
    if "b" in cfg:
        sm["b"] = float(cfg["b"])
    if "lambda" in cfg:
        sm["lambda"] = float(cfg["lambda"])
    wsc["stability_modulus"] = sm

    ccs = cfg.get("convergence_certificates", None)
    if ccs is not None:
        wsc["convergence_certificates"] = ccs

    # enforce baseline correctness hint for coupled targets
    if target_type == "cst" and ("cst" not in baseline.lower()) and ("coupled" not in baseline.lower()):
        wsc.setdefault("assumptions", []).append("CTP/CHT baseline: coupled Haar on CST")

    print(json.dumps(wsc, indent=2))

if __name__ == "__main__":
    main()
