"""
Nexa Language — Native Compiler (v23)
`nexa build file.nexa --target native`

Pipeline:
  1. Transpile .nexa → .py (Python source)
  2. Run Nuitka to compile .py → native binary

Falls back gracefully:
  - If nuitka not installed → suggest: pip install nuitka
  - If mingw/gcc not found  → show manual command

On Windows: emits a standalone .exe
On Linux:   emits a standalone ELF binary
"""
from __future__ import annotations
import os, sys, subprocess, shutil


def build_native(nexa_path: str, output_name: str = None) -> str:
    """Transpile .nexa → .py then compile to native via Nuitka."""
    if not os.path.exists(nexa_path):
        print(f"  ❌ File not found: {nexa_path}"); return ""

    # Step 1: Transpile to Python
    py_path = _transpile_to_py(nexa_path)
    if not py_path: return ""

    print(f"  ⚙️  Python source: {py_path}")

    # Step 2: Compile via Nuitka
    if not _nuitka_available():
        print(f"  ⚠️  Nuitka not installed.")
        print(f"  💡 Install: pip install nuitka")
        print(f"  📦 Python source ready at: {py_path}")
        print(f"\n  Alternative — compile manually:")
        print(f"    python -m nuitka --standalone --onefile {py_path}")
        return py_path

    base = output_name or os.path.splitext(nexa_path)[0]
    cmd = [
        sys.executable, "-m", "nuitka",
        "--standalone",
        "--onefile",
        f"--output-dir={os.path.dirname(os.path.abspath(py_path))}",
        "--remove-output",
        "--quiet",
        py_path,
    ]
    print(f"  🔨 Compiling with Nuitka (this may take 30–120s)...")
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
        if result.returncode == 0:
            ext = ".exe" if sys.platform == "win32" else ""
            out = os.path.splitext(py_path)[0] + ext
            if os.path.exists(out):
                print(f"  ✅ Native binary → {out}")
                return out
            else:
                # Nuitka may output differently
                print(f"  ✅ Nuitka compilation complete. Check output dir.")
                return os.path.dirname(py_path)
        else:
            print(f"  ❌ Nuitka error:\n{result.stderr[:500]}")
    except subprocess.TimeoutExpired:
        print(f"  ⏱️  Nuitka compilation timed out (>300s). Run manually:")
        print(f"    python -m nuitka --standalone --onefile {py_path}")
    except Exception as e:
        print(f"  ❌ Nuitka failed: {e}")
    return py_path


def _transpile_to_py(nexa_path: str) -> str:
    """Transpile .nexa → .py using Nexa's transpiler."""
    from nexa_lang.lexer import Lexer
    from nexa_lang.parser import Parser
    from nexa_lang.transpiler import Transpiler

    src = open(nexa_path, encoding="utf-8").read()
    try:
        tokens = Lexer(src).tokenize()
        ast = Parser(tokens).parse()
        py_code = Transpiler().transpile(ast)
        out = os.path.splitext(nexa_path)[0] + "_native.py"
        with open(out, "w", encoding="utf-8") as f:
            f.write(py_code)
        return out
    except Exception as e:
        print(f"  ❌ Transpile error: {e}")
        return ""


def _nuitka_available() -> bool:
    try:
        result = subprocess.run([sys.executable, "-m", "nuitka", "--version"],
                                 capture_output=True, timeout=10)
        return result.returncode == 0
    except Exception:
        return False
