import os
import subprocess
from pathlib import Path
from rich.console import Console

console = Console()

def build_python_static(toolchain_prefix):
    base_dir = Path(__file__).resolve().parents[1]
    nfdos_dir = base_dir / "_nfdos"
    python_dir = nfdos_dir / "cpython"
    output_binary = nfdos_dir / "python"

    env = {
        **os.environ,
        "ARCH": "x86_64",
        "CROSS_COMPILE": f"{toolchain_prefix}/bin/x86_64-nfdos-linux-musl-",
    }

    os.chdir(nfdos_dir)

    if python_dir.exists():
        console.print("[yellow]🧹 Limpando build anterior...[/yellow]")
        if output_binary.exists():
            output_binary.unlink()
        os.chdir(python_dir)
        subprocess.run(["make", "distclean"], check=False)
        subprocess.run(["make", "autoreconf", "-fi"], check=False)
    else:
        console.print("[cyan]📥 Clonando repositório CPython...[/cyan]")
        subprocess.run(["git", "clone", "--depth=1", "https://github.com/python/cpython.git"], check=True)
        os.chdir(python_dir)

    console.print("[bold cyan]⚙️ Configurando CPython para build estático...[/]")
    configure_cmd = [
        "./configure",
        "--disable-shared",
        "--without-ensurepip",
        "--enable-optimizations",
        "--without-pymalloc",
        "--enable-ipv6",
        "ac_cv_file__dev_ptmx=no",
        "ac_cv_file__dev_ptc=no",
    ]

    env["LDFLAGS"] = "-static -lz"
    env["CFLAGS"] = "-Os -static -I/usr/include"

    subprocess.run(configure_cmd, env=env, check=True)

    console.print("[yellow]🔧 Compilando CPython (modo estático, otimizado)...[/yellow]")
    subprocess.run(["make", "LDFLAGS=-static", "LINKFORSHARED= ", f"-j{os.cpu_count()}", "python", "Modules/config.c"], check=True, env=env)

    # Força modo estático local (núcleo do Python estático + módulos essenciais)
    with open("Modules/Setup.local", "w") as f:
        f.write("*static*\n")

        # -------------------------------------------------------------
        # Compressão e I/O
        # -------------------------------------------------------------
        f.write("zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz\n")
        f.write("_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c\n")

        # -------------------------------------------------------------
        # Núcleo fundamental (Unicode, datetime, JSON, warnings, binascii)
        # -------------------------------------------------------------
        f.write("unicodedata unicodedata.c\n")
        f.write("_datetime _datetimemodule.c\n")
        f.write("_json _json.c\n")
        f.write("binascii binascii.c\n")
        # f.write("_warnings _warnings.c\n")

        # Hashing (útil para integridade, DNA, fingerprints, logs futuros)
        # f.write("_sha256 _sha256.c\n")
        # f.write("_sha512 _sha512.c\n")

        # -------------------------------------------------------------
        # Matemática + coleções
        # -------------------------------------------------------------
        f.write("math mathmodule.c\n")
        f.write("_struct _struct.c\n")
        f.write("array arraymodule.c\n")
        f.write("_collections _collectionsmodule.c\n")
        f.write("_heapq _heapqmodule.c\n")
        f.write("_bisect _bisectmodule.c\n")
        f.write("_weakref _weakref.c\n")

        # -------------------------------------------------------------
        # Execução e threads
        # -------------------------------------------------------------
        f.write("_functools _functoolsmodule.c\n")
        f.write("_operator _operator.c\n")
        f.write("_random _randommodule.c\n")
        f.write("_statistics _statisticsmodule.c\n")
        f.write("_sre _sre/sre.c\n")
        f.write("_codecs _codecsmodule.c\n")

        # -------------------------------------------------------------
        # Sistema POSIX básico
        # -------------------------------------------------------------
        f.write("_signal signalmodule.c\n")
        f.write("_thread _threadmodule.c\n")
        f.write("_posixsubprocess _posixsubprocess.c\n")
        f.write("resource resource.c\n")

        # Corrigido: nomes SEM underscore inicial
        f.write("select selectmodule.c\n")
        f.write("mmap mmapmodule.c\n")
        f.write("errno errnomodule.c\n")

        f.write("fcntl fcntlmodule.c\n")
        f.write("_locale _localemodule.c\n")
        f.write("_socket socketmodule.c\n")
        f.write("termios termios.c\n")
        f.write("time timemodule.c\n")
        f.write("pwd pwdmodule.c\n")  # opcional

        # -------------------------------------------------------------
        # Curses (dashboard)
        # -------------------------------------------------------------
        f.write("_curses _cursesmodule.c -lncursesw -lpanelw -lformw -ltinfo\n")
        f.write("_curses_panel _curses_panel.c -lpanelw -lncursesw -lformw -ltinfo\n")

        # -------------------------------------------------------------
        # Debug
        # -------------------------------------------------------------
        f.write("faulthandler faulthandler.c\n")
        # f.write("_trace _trace.c\n")

    # 🧠 1️⃣ Gera config.c agora
    console.print("[cyan]🧩 Regenerando Modules/config.c a partir de Setup.local...[/cyan]")
    subprocess.run(["make", "Modules/config.c"], check=True, env=env)

    # 🧠 2️⃣ Só agora compila o Python
    subprocess.run(["make", "LDFLAGS=-static", "LINKFORSHARED= ", f"-j{os.cpu_count()}", "python"], check=True, env=env)

    console.print("[green]✔ CPython compilado com sucesso![/green]")

    if (python_dir / "python").exists():
        (python_dir / "python").rename(output_binary)
        console.print(f"[bold green]➡️ Python estático disponível em:[/] {output_binary}")

    os.chdir(nfdos_dir)

def run():
    toolchain_prefix = Path.home() / "x-tools" / "x86_64-nfdos-linux-musl"
    build_python_static(toolchain_prefix)