#!/usr/bin/env python3
import os
import re
import subprocess
import shutil
from pathlib import Path

# Paths
SCRIPT_DIR = Path(__file__).parent.resolve()
PROJECT_ROOT = SCRIPT_DIR.parent.parent
BUILD_DIR = Path(os.environ["BUILD_DIR"]) if "BUILD_DIR" in os.environ else PROJECT_ROOT / "build/linux/x64/release/bundle"
OUTPUT_DIR = Path(os.environ.get("OUTPUT_DIR", PROJECT_ROOT))
ARCH_SUFFIX = os.environ.get("ARCH_SUFFIX", "x64")

# Package metadata
METADATA = {
    "name": "plezy",
    "license": "GPL-3.0",
    "vendor": "edde746",
    "maintainer": "edde746 <noreply@github.com>",
    "url": "https://github.com/edde746/plezy",
    "description": "A modern Plex and Jellyfin client for desktop and mobile",
}

# Icon sizes to generate
ICON_SIZES = [16, 32, 48, 64, 128, 256, 512]

# Architecture mappings per package format
ARCH_MAP = {
    "x64": {"deb": "amd64", "rpm": "x86_64", "pacman": "x86_64"},
    "arm64": {"deb": "arm64", "rpm": "aarch64", "pacman": "aarch64"},
}

# Distro-specific configuration
DISTROS = {
    "deb": {
        "type": "deb",
        "category": "video",
        "ext": "deb",
        "compression": ["--deb-compression", "xz", "--deb-priority", "optional"],
        "depends": [
            "libgtk-3-0",
            "libmpv2 | libmpv1",
            "libepoxy0",
            "libasound2",
            "libevdev2",
            "libglib2.0-0",
        ],
    },
    "rpm": {
        "type": "rpm",
        "category": "Multimedia",
        "ext": "rpm",
        "compression": ["--rpm-compression", "xzmt"],
        "depends": [
            "gtk3",
            "mpv-libs",
            "libepoxy",
            "alsa-lib",
            "libevdev",
            "glib2",
        ],
    },
    "pacman": {
        "type": "pacman",
        "category": None,
        "ext": "pkg.tar.zst",
        "compression": ["--pacman-compression", "zstd"],
        "depends": [
            "gtk3",
            "mpv",
            "libepoxy",
            "alsa-lib",
            "libevdev",
            "glib2",
        ],
    },
}


def get_version() -> str:
    """Extract version from pubspec.yaml."""
    pubspec = PROJECT_ROOT / "pubspec.yaml"
    content = pubspec.read_text()
    match = re.search(r"^version:\s*(.+)$", content, re.MULTILINE)
    if not match:
        raise RuntimeError("Could not find version in pubspec.yaml")
    return match.group(1).split("+")[0]


def generate_icons():
    """Generate icons at multiple sizes using ImageMagick."""
    print("Generating icons...")
    source = PROJECT_ROOT / "assets/plezy.png"

    for size in ICON_SIZES:
        dest_dir = SCRIPT_DIR / f"icons/{size}x{size}"
        dest_dir.mkdir(parents=True, exist_ok=True)
        dest = dest_dir / "plezy.png"

        # Try magick (ImageMagick 7) first, then convert (ImageMagick 6)
        for cmd in ["magick", "convert"]:
            if shutil.which(cmd):
                subprocess.run([cmd, str(source), "-resize", f"{size}x{size}", str(dest)], check=True)
                break
        else:
            print(f"Warning: ImageMagick not found, copying original icon for {size}x{size}")
            shutil.copy(source, dest)


def get_file_mappings() -> list[str]:
    """Get file mappings for fpm."""
    mappings = [
        f"{BUILD_DIR}/=/opt/plezy/",
        f"{SCRIPT_DIR}/com.edde746.plezy.desktop=/usr/share/applications/com.edde746.plezy.desktop",
        f"{SCRIPT_DIR}/plezy.sh=/usr/bin/plezy",
    ]

    for size in ICON_SIZES:
        mappings.append(
            f"{SCRIPT_DIR}/icons/{size}x{size}/plezy.png=/usr/share/icons/hicolor/{size}x{size}/apps/plezy.png"
        )

    return mappings


def build_package(distro: str, version: str):
    """Build a package for the specified distro."""
    config = DISTROS[distro]
    arch = ARCH_MAP[ARCH_SUFFIX][distro]
    output_file = OUTPUT_DIR / f"{METADATA['name']}-linux-{ARCH_SUFFIX}.{config['ext']}"

    print(f"Building .{config['ext']} package ({arch})...")

    cmd = [
        "fpm",
        "-s", "dir",
        "-t", config["type"],
        "-n", METADATA["name"],
        "-v", version,
        "--iteration", "1",
        "--license", METADATA["license"],
        "--vendor", METADATA["vendor"],
        "--maintainer", METADATA["maintainer"],
        "--url", METADATA["url"],
        "--description", METADATA["description"],
        "--architecture", arch,
    ]

    if config["category"]:
        cmd.extend(["--category", config["category"]])

    for dep in config["depends"]:
        cmd.extend(["--depends", dep])

    cmd.extend(config["compression"])

    cmd.extend([
        "--after-install", str(SCRIPT_DIR / "after-install.sh"),
        "--after-remove", str(SCRIPT_DIR / "after-remove.sh"),
        "--package", str(output_file),
    ])

    cmd.extend(get_file_mappings())

    subprocess.run(cmd, check=True)
    print(f"Created: {output_file}")


def main():
    # Verify build exists
    if not BUILD_DIR.exists():
        print(f"Error: Build directory not found at {BUILD_DIR}")
        print("Please run 'flutter build linux --release' first or set BUILD_DIR")
        exit(1)

    version = get_version()
    print(f"Building {ARCH_SUFFIX} packages for {METADATA['name']} version {version}")

    # Make scripts executable
    for script in ["plezy.sh", "after-install.sh", "after-remove.sh"]:
        (SCRIPT_DIR / script).chmod(0o755)

    # Generate icons
    generate_icons()

    # Build all packages
    for distro in DISTROS:
        build_package(distro, version)

    print("\nAll packages built successfully!")
    for f in sorted(OUTPUT_DIR.glob(f"{METADATA['name']}-linux-{ARCH_SUFFIX}.*")):
        print(f"  {f}")


if __name__ == "__main__":
    main()
