"""
Poe2VisualTool Commercial Build & Packaging Automation Pipeline
Quy trình tự động hóa đóng gói phát hành sản phẩm thương mại:
  1. Biên dịch C++23 Native Core Engine (Release x64).
  2. Kích hoạt Cổng Kiểm Định Chất Lượng (Quality Gate: C++ 33 checks & Pytest 31 checks).
  3. Đóng băng Python Companion thành tệp thực thi độc lập (PyInstaller --noconsole).
  4. Lắp ráp gói phân phối Standalone (Zero-Dependency) vào thư mục dist/Poe2VisualTool/.
  5. Đóng gói tệp nén phát hành Poe2VisualTool_v1.0.0_Portable.zip.
Bản quyền 2026 Poe2VisualTool.
"""

from __future__ import annotations

import os
import shutil
import subprocess
import sys
import zipfile
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
DIST_DIR = ROOT / "dist"
PACKAGE_DIR = DIST_DIR / "Poe2VisualTool"
RELEASE_ZIP = DIST_DIR / "Poe2VisualTool_v1.2.0_Portable.zip"


def print_step(step_num: int, title: str):
    print("\n" + "=" * 70)
    print(f"  [BƯỚC {step_num}] {title.upper()}")
    print("=" * 70)


def run_command(cmd: list[str], cwd: Path, desc: str) -> None:
    print(f"[*] Đang thực thi: {' '.join(cmd)}")
    result = subprocess.run(cmd, cwd=str(cwd), text=True)
    if result.returncode != 0:
        print(f"[❌ LỖI] {desc} thất bại với mã lỗi: {result.returncode}")
        sys.exit(result.returncode)
    print(f"[✓] {desc} hoàn tất thành công!")


def step_1_build_cpp():
    print_step(1, "Biên dịch C++23 Native Core Engine (Release x64)")
    build_dir = ROOT / "build"
    build_dir.mkdir(exist_ok=True)
    run_command(["cmake", "-B", "build", "-S", ".", "-DCMAKE_BUILD_TYPE=Release"], ROOT, "Cấu hình CMake")
    run_command(["cmake", "--build", "build", "--config", "Release"], ROOT, "Biên dịch C++ Release")


def step_2_quality_gate():
    print_step(2, "Kiểm định chất lượng phần mềm (Quality Gate)")
    
    # 2.1 C++ Unit Tests
    test_exe = ROOT / "bin" / "Release" / "Poe2VisualTool_Tests.exe"
    if not test_exe.is_file():
        test_exe = ROOT / "bin" / "Poe2VisualTool_Tests.exe"
    if not test_exe.is_file():
        print("[!] Cảnh báo: Không tìm thấy Poe2VisualTool_Tests.exe, bỏ qua bước test C++.")
    else:
        run_command([str(test_exe)], ROOT, "C++ Native Core Unit Tests (69 checks)")

    # 2.2 Python Pytest Suite
    run_command([sys.executable, "-m", "pytest"], ROOT, "Python Companion & Commercial Test Suite (37 checks)")


def step_3_bundle_python():
    print_step(3, "Đóng gói Python Companion thành Native Standalone Exe")
    
    # Dọn dẹp thư mục dist và build tạm thời của PyInstaller
    if PACKAGE_DIR.exists():
        shutil.rmtree(PACKAGE_DIR, ignore_errors=True)
    pyinstaller_work = ROOT / "build" / "pyinstaller_work"
    if pyinstaller_work.exists():
        shutil.rmtree(pyinstaller_work, ignore_errors=True)

    # Tìm vị trí customtkinter để gom tài liệu giao diện
    import customtkinter
    ctk_path = Path(customtkinter.__file__).parent

    pyinstaller_cmd = [
        sys.executable,
        "-m",
        "PyInstaller",
        "--noconfirm",
        "--onedir",
        "--windowed",
        "--name",
        "Poe2VisualCompanion",
        "--add-data",
        f"{ctk_path};customtkinter",
        "--distpath",
        str(DIST_DIR),
        "--workpath",
        str(pyinstaller_work),
        "--specpath",
        str(ROOT / "build"),
        str(ROOT / "run_tool.py"),
    ]

    run_command(pyinstaller_cmd, ROOT, "PyInstaller Standalone Freeze")


def step_4_assemble_package():
    print_step(4, "Lắp ráp gói phân phối thương mại độc lập (Zero-Dependency)")
    
    companion_dir = DIST_DIR / "Poe2VisualCompanion"
    if not companion_dir.exists():
        print("[❌ LỖI] Không tìm thấy thư mục xuất xưởng Poe2VisualCompanion!")
        sys.exit(1)

    # Đổi tên hoặc di chuyển về PACKAGE_DIR
    if PACKAGE_DIR.exists():
        shutil.rmtree(PACKAGE_DIR, ignore_errors=True)
    shutil.move(str(companion_dir), str(PACKAGE_DIR))

    # 1. Sao chép C++ Engine Poe2VisualTool.exe
    bin_exe = ROOT / "bin" / "Release" / "Poe2VisualTool.exe"
    if not bin_exe.is_file():
        bin_exe = ROOT / "bin" / "Poe2VisualTool.exe"
    if bin_exe.is_file():
        shutil.copy2(bin_exe, PACKAGE_DIR / "Poe2VisualTool.exe")
        print(f"[+] Đã tích hợp C++ Engine: {bin_exe.name}")

    # 2. Sao chép config.toml & offsets.toml
    for cfg in ("config.toml", "offsets.toml"):
        config_file = ROOT / cfg
        if config_file.is_file():
            shutil.copy2(config_file, PACKAGE_DIR / cfg)
            print(f"[+] Đã tích hợp file cấu hình: {cfg}")

    # 3. Tạo kịch bản khởi động Launcher trực quan Poe2VisualTool_Launcher.bat
    launcher_bat = PACKAGE_DIR / "Poe2VisualTool.bat"
    launcher_bat.write_text(
        "@echo off\r\n"
        "chcp 65001 >nul\r\n"
        "title Poe2VisualTool Launcher (2026)\r\n"
        "cd /d \"%~dp0\"\r\n"
        "start \"\" \"%~dp0Poe2VisualCompanion.exe\"\r\n"
        "exit\r\n",
        encoding="utf-8",
    )
    print("[+] Đã tạo Launcher: Poe2VisualTool.bat")

    # 4. Sao chép tài liệu
    for doc_name in ("README.md",):
        doc_src = ROOT / doc_name
        if doc_src.is_file():
            shutil.copy2(doc_src, PACKAGE_DIR / doc_name)


def step_5_create_zip():
    print_step(5, "Đóng gói tệp nén thương mại Portable (.zip)")
    if RELEASE_ZIP.exists():
        RELEASE_ZIP.unlink()

    print(f"[*] Đang nén toàn bộ thư mục {PACKAGE_DIR.name} vào {RELEASE_ZIP.name}...")
    with zipfile.ZipFile(RELEASE_ZIP, "w", zipfile.ZIP_DEFLATED) as zipf:
        for root_path, _, files in os.walk(PACKAGE_DIR):
            for file in files:
                file_full = Path(root_path) / file
                arcname = file_full.relative_to(DIST_DIR)
                zipf.write(file_full, arcname)

    size_mb = RELEASE_ZIP.stat().st_size / (1024 * 1024)
    print(f"[✓] Đã tạo thành công gói phát hành: {RELEASE_ZIP} ({size_mb:.2f} MB)")


def main():
    if hasattr(sys.stdout, "reconfigure"):
        sys.stdout.reconfigure(encoding="utf-8", errors="replace")
    if hasattr(sys.stderr, "reconfigure"):
        sys.stderr.reconfigure(encoding="utf-8", errors="replace")

    print("\n" + "=" * 70)
    print("  POE2VISUALTOOL COMMERCIAL PACKAGING & RELEASE PIPELINE")
    print("  Phiên bản 1.2.0-RELEASE · Hỗ trợ Path of Exile 2 (2026)")
    print("=" * 70)

    step_1_build_cpp()
    step_2_quality_gate()
    step_3_bundle_python()
    step_4_assemble_package()
    step_5_create_zip()

    print("\n" + "=" * 70)
    print("  🎉 QUY TRÌNH ĐÓNG GÓI THƯƠNG MẠI HOÀN TẤT THÀNH CÔNG 100%!")
    print(f"  • Thư mục sản phẩm : {PACKAGE_DIR}")
    print(f"  • Gói phát hành ZIP: {RELEASE_ZIP}")
    print("=" * 70 + "\n")


if __name__ == "__main__":
    main()
