#!/usr/bin/env bash
#
# Shared build functions for LedGrab distribution packaging.
# Sourced by build-dist.sh (Linux) and build-dist-windows.sh (Windows).
#
# Expected variables set by the caller before sourcing:
#   SCRIPT_DIR, BUILD_DIR, DIST_DIR, SERVER_DIR, APP_DIR

# ── Version detection ────────────────────────────────────────

detect_version() {
    # Usage: detect_version [explicit_version]
    local version="${1:-}"

    if [ -z "$version" ]; then
        version=$(git describe --tags --exact-match 2>/dev/null || true)
    fi
    if [ -z "$version" ]; then
        version="${GITEA_REF_NAME:-${GITHUB_REF_NAME:-}}"
    fi
    if [ -z "$version" ]; then
        version=$(grep -oP '^version\s*=\s*"\K[^"]+' "$SERVER_DIR/pyproject.toml" 2>/dev/null || echo "0.0.0")
    fi

    VERSION_CLEAN="${version#v}"

    # Stamp the resolved version into pyproject.toml so that
    # importlib.metadata reads the correct value at runtime.
    sed -i "s/^version = .*/version = \"${VERSION_CLEAN}\"/" "$SERVER_DIR/pyproject.toml"
}

# ── Clean previous build ─────────────────────────────────────

clean_dist() {
    if [ -d "$DIST_DIR" ]; then
        echo "  Cleaning previous build..."
        rm -rf "$DIST_DIR"
    fi
    mkdir -p "$DIST_DIR"
}

# ── Build frontend ───────────────────────────────────────────

build_frontend() {
    echo "  Building frontend bundle..."
    (cd "$SERVER_DIR" && npm ci --loglevel error && npm run build) 2>&1 | {
        grep -v 'RemoteException' || true
    }
}

# ── Copy application files ───────────────────────────────────

copy_app_files() {
    echo "  Copying application files..."
    mkdir -p "$APP_DIR"

    cp -r "$SERVER_DIR/src" "$APP_DIR/src"
    cp -r "$SERVER_DIR/config" "$APP_DIR/config"
    mkdir -p "$DIST_DIR/data" "$DIST_DIR/logs"

    # Clean up source maps and __pycache__
    find "$APP_DIR" -name "*.map" -delete 2>/dev/null || true
    find "$APP_DIR" -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
}

# ── Site-packages cleanup ────────────────────────────────────
#
# Strips tests, type stubs, unused submodules, and debug symbols
# from the installed site-packages directory.
#
# Args:
#   $1 — path to site-packages directory
#   $2 — native extension suffix: "pyd" (Windows) or "so" (Linux)
#   $3 — native lib suffix for OpenCV ffmpeg: "dll" or "so"

cleanup_site_packages() {
    local sp_dir="$1"
    local ext_suffix="${2:-so}"
    local lib_suffix="${3:-so}"

    echo "  Cleaning up site-packages to reduce size..."

    # ── Generic cleanup ──────────────────────────────────────
    find "$sp_dir" -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
    find "$sp_dir" -type d -name tests -exec rm -rf {} + 2>/dev/null || true
    find "$sp_dir" -type d -name test -exec rm -rf {} + 2>/dev/null || true
    find "$sp_dir" -type d -name "*.dist-info" -exec rm -rf {} + 2>/dev/null || true
    find "$sp_dir" -name "*.pyi" -delete 2>/dev/null || true

    # ── pip / setuptools (not needed at runtime) ─────────────
    rm -rf "$sp_dir"/pip "$sp_dir"/pip-* 2>/dev/null || true
    rm -rf "$sp_dir"/setuptools "$sp_dir"/setuptools-* "$sp_dir"/pkg_resources 2>/dev/null || true
    rm -rf "$sp_dir"/_distutils_hack 2>/dev/null || true

    # ── OpenCV ───────────────────────────────────────────────
    local cv2_dir="$sp_dir/cv2"
    if [ -d "$cv2_dir" ]; then
        # Remove ffmpeg (28 MB on Windows), Haar cascades, dev files
        rm -f "$cv2_dir"/opencv_videoio_ffmpeg*."$lib_suffix" 2>/dev/null || true
        rm -rf "$cv2_dir/data" "$cv2_dir/gapi" "$cv2_dir/misc" "$cv2_dir/utils" 2>/dev/null || true
        rm -rf "$cv2_dir/typing_stubs" "$cv2_dir/typing" 2>/dev/null || true
    fi

    # ── NumPy ────────────────────────────────────────────────
    # Remove unused submodules (only core, fft, random are used)
    for mod in polynomial linalg ma lib distutils f2py typing _pyinstaller; do
        rm -rf "$sp_dir/numpy/$mod" 2>/dev/null || true
    done
    rm -rf "$sp_dir/numpy/tests" "$sp_dir/numpy/*/tests" 2>/dev/null || true

    # ── Pillow (only used for system tray icon) ──────────────
    rm -rf "$sp_dir/PIL/tests" 2>/dev/null || true
    # Remove unused image format plugins (keep JPEG, PNG, ICO, BMP)
    for plugin in Eps Gif Tiff Webp Psd Pcx Xbm Xpm Dds Ftex Gbr Grib \
                  Icns Im Imt Iptc McIrdas Mpo Msp Pcd Pixar Ppm Sgi \
                  Spider Sun Tga Wal Wmf; do
        rm -f "$sp_dir/PIL/${plugin}ImagePlugin.py" 2>/dev/null || true
        rm -f "$sp_dir/PIL/${plugin}ImagePlugin.pyc" 2>/dev/null || true
    done

    # ── zeroconf ─────────────────────────────────────────────
    rm -rf "$sp_dir/zeroconf/_services" 2>/dev/null || true

    # ── Strip debug symbols ──────────────────────────────────
    if command -v strip &>/dev/null; then
        echo "  Stripping debug symbols from .$ext_suffix files..."
        find "$sp_dir" -name "*.$ext_suffix" -exec strip --strip-debug {} \; 2>/dev/null || true
    fi

    # ── Remove .py source (keep .pyc bytecode) ───────────────
    echo "  Removing .py source from site-packages (keeping .pyc)..."
    find "$sp_dir" -name "*.py" ! -name "__init__.py" -delete 2>/dev/null || true

    # ── Remove wled_controller if pip-installed ───────────────
    rm -rf "$sp_dir"/wled_controller* "$sp_dir"/wled*.dist-info 2>/dev/null || true

    local cleaned_size
    cleaned_size=$(du -sh "$sp_dir" | cut -f1)
    echo "  Site-packages after cleanup: $cleaned_size"
}
