#!/usr/bin/env python3
"""VMS CAS MASTER RUN — SymPy mirror of CAS_MASTER_RUN.m

Runs CAS_F0000_VERIFY ... CAS_F0031_VERIFY sequentially,
then performs cross-block constant consistency checks.

F0000 = geometric scaling lemmas (axiomatic root)
F0001–F0031 = physics corollaries

Usage:
    pip install sympy
    python run_master.py
"""

import importlib
import json
import os
import platform
import sys
import time
import traceback
from datetime import datetime, timezone

# Ensure we can import from the package root
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

import constants


def main():
    print("=== VMS CAS MASTER RUN (SymPy) ===\n")
    t_start = time.time()

    blocks = [
        ("F0000", "f0000.CAS_F0000_VERIFY"),
        ("F0001", "f0001.CAS_F0001_VERIFY"),
        ("F0002", "f0002.CAS_F0002_VERIFY"),
        ("F0003", "f0003.CAS_F0003_VERIFY"),
        ("F0004", "f0004.CAS_F0004_VERIFY"),
        ("F0005", "f0005.CAS_F0005_VERIFY"),
        ("F0006", "f0006.CAS_F0006_VERIFY"),
        ("F0007", "f0007.CAS_F0007_VERIFY"),
        ("F0008", "f0008.CAS_F0008_VERIFY"),
        ("F0009", "f0009.CAS_F0009_VERIFY"),
        ("F0010", "f0010.CAS_F0010_VERIFY"),
        ("F0011", "f0011.CAS_F0011_VERIFY"),
        ("F0012", "f0012.CAS_F0012_VERIFY"),
        ("F0013", "f0013.CAS_F0013_VERIFY"),
        ("F0014", "f0014.CAS_F0014_VERIFY"),
        ("F0015", "f0015.CAS_F0015_VERIFY"),
        ("F0016", "f0016.CAS_F0016_VERIFY"),
        ("F0017", "f0017.CAS_F0017_VERIFY"),
        ("F0018", "f0018.CAS_F0018_VERIFY"),
        ("F0019", "f0019.CAS_F0019_VERIFY"),
        ("F0020", "f0020.CAS_F0020_VERIFY"),
        ("F0021", "f0021.CAS_F0021_VERIFY"),
        ("F0022", "f0022.CAS_F0022_VERIFY"),
        ("F0023", "f0023.CAS_F0023_VERIFY"),
        ("F0024", "f0024.CAS_F0024_VERIFY"),
        ("F0025", "f0025.CAS_F0025_VERIFY"),
        ("F0026", "f0026.CAS_F0026_VERIFY"),
        ("F0027", "f0027.CAS_F0027_VERIFY"),
        ("F0028", "f0028.CAS_F0028_VERIFY"),
        ("F0029", "f0029.CAS_F0029_VERIFY"),
        ("F0030", "f0030.CAS_F0030_VERIFY"),
        ("F0031", "f0031.CAS_F0031_VERIFY"),
    ]

    n_blocks = len(blocks)
    results = []
    constants.clear()

    # Add __init__.py files if needed
    for label, mod_path in blocks:
        pkg = mod_path.split(".")[0]
        init_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), pkg, "__init__.py")
        if not os.path.exists(init_path):
            with open(init_path, "w") as f:
                pass

    for i, (label, mod_path) in enumerate(blocks):
        print(f"[{i+1:02d}/{n_blocks}] {label} ... ", end="", flush=True)
        try:
            mod = importlib.import_module(mod_path)
            # Force reload in case of repeated runs
            importlib.reload(mod)
            mod.run()
            results.append((label, "PASS", ""))
            print(f"  → PASS")
        except Exception as e:
            err = traceback.format_exc()
            results.append((label, "FAIL", err))
            print(f"  → FAIL")
            print(f"    {e}")

    # ── Global consistency checks ──
    print("\n=== GLOBAL CONSISTENCY CHECKS ===")

    global_pass = True

    # 1) Per-constant consistency
    const_pass, const_lines = constants.check_consistency()
    global_pass = global_pass and const_pass
    for line in const_lines:
        print(line)

    # 2) Identity checks
    id_pass, id_lines = constants.check_identities()
    global_pass = global_pass and id_pass
    for line in id_lines:
        print(line)

    # ── Summary ──
    n_pass = sum(1 for _, s, _ in results if s == "PASS")
    n_fail = n_blocks - n_pass
    elapsed = time.time() - t_start

    print(f"\n=== SUMMARY ===")
    print(f"Blocks: {n_pass} PASS, {n_fail} FAIL")
    print(f"Global: {'PASS' if global_pass else 'FAIL'}")
    print(f"Elapsed: {elapsed:.1f}s")

    if n_fail == 0 and global_pass:
        print(f"\nSTACK CLOSED: 32 green lights (F0000–F0031) + global closure.")
    else:
        print(f"\nFailures detected:")
        for label, status, err in results:
            if status == "FAIL":
                print(f"\n  {label}:")
                print(f"  {err[:500]}")

    # ── Write JSON audit report ──
    report = {
        "audit": "VMS CAS verification",
        "engine": "SymPy",
        "timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
        "python_version": platform.python_version(),
        "sympy_version": _get_sympy_version(),
        "blocks_run": n_blocks,
        "blocks_passed": n_pass,
        "blocks_failed": n_fail,
        "global_consistency": "PASS" if global_pass else "FAIL",
        "elapsed_seconds": round(elapsed, 2),
        "results": {label: status for label, status, _ in results},
        "constants_registered": sorted(constants.get_registry().keys()),
    }

    report_path = os.path.join(
        os.path.dirname(os.path.abspath(__file__)), "audit_report.json"
    )
    with open(report_path, "w") as f:
        json.dump(report, f, indent=2)
    print(f"\nReport written to: audit_report.json")

    return n_fail == 0 and global_pass


def _get_sympy_version():
    """Get SymPy version string."""
    try:
        import sympy
        return sympy.__version__
    except Exception:
        return "unknown"


if __name__ == "__main__":
    success = main()
    sys.exit(0 if success else 1)
