"""
Nexa Language — nexa build-vm command (Phase 7 / v27)
Auto-compile the native C VM for the current platform.

Usage:
    nexa build-vm               # compile nexa_vm.c with best available compiler
    nexa build-vm --debug       # compile with debug symbols
    nexa build-vm --force       # recompile even if .so/.dll present
    nexa build-vm --check       # check VM build status without compiling

The compiled C VM is used automatically by fast_vm.py when present,
giving 5-15× speedup over the pure-Python bytecode emulator.
"""
from __future__ import annotations
import os, sys, subprocess, shutil, platform
from pathlib import Path


def _find_compiler() -> tuple[str, list[str]]:
    """Find the best available C compiler on this platform."""
    system = platform.system()

    if system == "Windows":
        # Try MSVC first (cl.exe), then MinGW gcc
        if shutil.which("cl"):
            return "cl", []
        if shutil.which("gcc"):
            return "gcc", ["-shared", "-fPIC", "-O3"]
        if shutil.which("clang"):
            return "clang", ["-shared", "-fPIC", "-O3"]
        return "", []

    if system == "Darwin":
        if shutil.which("clang"):
            return "clang", ["-shared", "-fPIC", "-O3", "-dynamiclib"]
        if shutil.which("gcc"):
            return "gcc", ["-shared", "-fPIC", "-O3"]
        return "", []

    # Linux
    if shutil.which("gcc"):
        return "gcc", ["-shared", "-fPIC", "-O3"]
    if shutil.which("clang"):
        return "clang", ["-shared", "-fPIC", "-O3"]
    return "", []


def _vm_paths() -> tuple[Path, Path]:
    """Return (source .c path, output .so/.dll path)."""
    pkg_dir = Path(__file__).parent
    src  = pkg_dir / "nexa_vm.c"
    ext  = ".dll" if platform.system() == "Windows" else \
           ".dylib" if platform.system() == "Darwin" else ".so"
    out  = pkg_dir / f"nexa_vm{ext}"
    return src, out


def check_vm_status() -> dict:
    """Return VM build status info."""
    src, out = _vm_paths()
    compiler, _ = _find_compiler()
    return {
        "source_exists": src.exists(),
        "compiled_exists": out.exists(),
        "compiler": compiler or "none found",
        "platform": platform.system(),
        "out_path": str(out),
        "src_path": str(src),
    }


def build_vm(debug: bool = False, force: bool = False) -> bool:
    """
    Compile nexa_vm.c to a shared library for the current platform.
    Returns True on success, False on failure.
    """
    src, out = _vm_paths()

    if not src.exists():
        print(f"  ❌ Source not found: {src}")
        print(f"     Ensure nexa_vm.c is in the nexa_lang package directory.")
        return False

    if out.exists() and not force:
        print(f"  ✅ C VM already compiled: {out}")
        print(f"     Use --force to recompile.")
        return True

    compiler, flags = _find_compiler()
    if not compiler:
        print("  ❌ No C compiler found (tried gcc, clang, cl).")
        print("     Install one of:")
        if platform.system() == "Windows":
            print("       - Visual Studio Build Tools (MSVC)")
            print("       - MinGW-w64: https://www.mingw-w64.org")
        else:
            print("       - gcc: sudo apt install gcc")
            print("       - clang: sudo apt install clang")
        return False

    if debug:
        flags = [f for f in flags if f != "-O3"] + ["-g", "-O0", "-DDEBUG"]
        out = out.with_name(out.stem + "_debug" + out.suffix)

    print(f"\n  🔨 Compiling Nexa C VM...")
    print(f"     Compiler : {compiler}")
    print(f"     Source   : {src}")
    print(f"     Output   : {out}")
    print(f"     Flags    : {' '.join(flags)}")

    if platform.system() == "Windows" and compiler == "cl":
        # MSVC syntax
        cmd = f'cl /LD /O2 /Fe:"{out}" "{src}"'
    else:
        flags_str = " ".join(flags)
        cmd = f'{compiler} {flags_str} -o "{out}" "{src}"'

    print(f"  $ {cmd}")
    rc = subprocess.call(cmd, shell=True)

    if rc == 0:
        size_kb = out.stat().st_size // 1024
        print(f"\n  ✅ C VM built successfully! ({size_kb} KB)")
        print(f"     nexa run will now use the native C VM automatically.")
        print(f"     Expected speedup: 5–15× over Python bytecode emulator.")
        return True
    else:
        print(f"\n  ❌ Compilation failed (exit code {rc}).")
        print(f"     Check compiler output above for errors.")
        return False


def run_build_vm(args: list):
    """Entry point for `nexa build-vm` CLI command."""
    debug  = "--debug"  in args
    force  = "--force"  in args
    check  = "--check"  in args

    if check:
        status = check_vm_status()
        print(f"\n  🔍 Nexa C VM Status")
        print(f"  {'─' * 40}")
        print(f"  Platform    : {status['platform']}")
        print(f"  Compiler    : {status['compiler']}")
        print(f"  Source (.c) : {'✅' if status['source_exists'] else '❌'} {status['src_path']}")
        print(f"  Compiled    : {'✅' if status['compiled_exists'] else '❌'} {status['out_path']}")
        if status["compiled_exists"]:
            print(f"\n  ✅ Native C VM is available — nexa run will use it automatically.")
        else:
            print(f"\n  ⚠️  Native C VM not built. Run: nexa build-vm")
        return

    success = build_vm(debug=debug, force=force)
    sys.exit(0 if success else 1)
