#!/usr/bin/env python3
"""Archive un module PrestaShop pour livraison WooCommerce."""

from __future__ import annotations

import argparse
import shutil
import zipfile
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]

EXCLUDE_DIR_NAMES = {".git", "__MACOSX", ".cursor"}
EXCLUDE_FILE_NAMES = {
    ".DS_Store",
    ".gitignore",
    "config_fr.xml",
    "error_log",
    "rand.php",
    ".php-cs-fixer.dist.php",
    ".php-cs-fixer.cache",
}
EXCLUDE_SUFFIXES = {".csv", ".txt", ".log"}


def should_include(path: Path, module_src: Path) -> bool:
    rel = path.relative_to(module_src)
    for part in rel.parts:
        if part in EXCLUDE_DIR_NAMES:
            return False
    if path.name in EXCLUDE_FILE_NAMES:
        return False
    if path.suffix.lower() in EXCLUDE_SUFFIXES:
        return False
    if "log" in rel.parts and path.name != "index.php":
        return False
    return True


def package_module(module_src: Path, module_name: str, version: str, out_dir: Path | None = None) -> Path:
    out_dir = out_dir or ROOT / "exports" / f"{module_name}-product"
    staging = out_dir / "_staging" / module_name
    if staging.exists():
        shutil.rmtree(staging.parent)
    staging.mkdir(parents=True)

    for path in sorted(module_src.rglob("*")):
        if not path.is_file() or not should_include(path, module_src):
            continue
        rel = path.relative_to(module_src)
        dest = staging / rel
        dest.parent.mkdir(parents=True, exist_ok=True)
        shutil.copy2(path, dest)

    for subdir in ("log", "export", "import"):
        target = staging / subdir
        target.mkdir(parents=True, exist_ok=True)
        index_src = module_src / subdir / "index.php"
        if index_src.is_file():
            shutil.copy2(index_src, target / "index.php")

    out_dir.mkdir(parents=True, exist_ok=True)
    zip_path = out_dir / f"{module_name}-{version}.zip"
    with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf:
        for path in sorted(staging.rglob("*")):
            if path.is_file():
                arcname = f"{module_name}/{path.relative_to(staging).as_posix()}"
                zf.write(path, arcname)

    shutil.rmtree(staging.parent)
    return zip_path


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--src", type=Path, required=True)
    parser.add_argument("--name", required=True)
    parser.add_argument("--version", required=True)
    parser.add_argument("--out-dir", type=Path, default=None)
    args = parser.parse_args()

    zip_path = package_module(args.src, args.name, args.version, args.out_dir)
    print(f"Archive : {zip_path}")
    print(f"Taille  : {zip_path.stat().st_size // 1024} Ko")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
