#!/bin/bash

# BleachBit xzm Module Builder for Porteus
# Version: 2026-09-25
#
# Copyright 2023-2030, Blaze, Dankov, Russia
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

export LC_ALL=C
export XZ_OPT="-T0"

PRGNAM=${PRGNAM:-bleachbit}
BUILD=${BUILD:-1}
OUTPUT=${OUTPUT:-/tmp}
TMPDIR=/tmp/portch
SRC="$TMPDIR/src"
PKG="$TMPDIR/package-$PRGNAM"
PKGINFO="$PKG/var/lib/pkgtools/packages"
ARCH=$(uname -m)

BOLD=$'\033[1m'
CYAN=$'\033[96m'
GREEN=$'\033[92m'
YELLOW=$'\033[93m'
RED=$'\033[91m'
RESET=$'\033[0m'

cleanup() {
    rm -rf "$TMPDIR" 2>/dev/null
}
trap cleanup EXIT INT TERM HUP

[ "$(id -u)" -ne 0 ] && { printf "\n${RED}Error: You need to be root to run this script.${RESET}\n"; exit 1; }

get_latest_tag() {
    local tag=""

    if command -v curl >/dev/null 2>&1; then
        tag=$(curl -fsSL --max-time 20 \
            "https://api.github.com/repos/bleachbit/bleachbit/releases/latest" 2>/dev/null |
            sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' |
            head -n1)
    fi

    if [ -z "$tag" ] && command -v wget >/dev/null 2>&1; then
        tag=$(wget --spider -S "https://github.com/bleachbit/bleachbit/releases/latest" 2>&1 |
            grep -i "Location:" |
            sed -n 's#.*/tag/##p' |
            tail -n1 |
            tr -d '\r')
    fi

    if [ -z "$tag" ] && command -v lynx >/dev/null 2>&1; then
        tag=$(lynx -head -dump "https://github.com/bleachbit/bleachbit/releases/latest" 2>/dev/null |
            grep -i "Location:" |
            sed -n 's#.*/tag/##p' |
            head -n1 |
            tr -d '\r')
    fi

    printf '%s' "$tag"
}

printf "\nFetching latest release info...\n"
TAG=$(get_latest_tag)
[[ -z "$TAG" ]] && { printf "${RED}Failed to determine version.${RESET}\n"; exit 1; }

VERSION=${TAG#v}
SOURCE="https://github.com/bleachbit/bleachbit/archive/refs/tags/${TAG}.tar.gz"

if [[ -f "/usr/bin/bleachbit" ]]; then
    MYVER=$(basename /var/lib/pkgtools/packages/bleachbit-* 2>/dev/null | cut -d'-' -f2 | sort -V | tail -n1)
    printf "[${GREEN}OK${RESET}] Installed version: ${YELLOW}%s${RESET}\n" "${MYVER:-Unknown}"
    if [[ "${MYVER:-}" == "$VERSION" ]]; then
        printf "You already have the latest ${GREEN}%s${RESET} version of %s.\n" "$MYVER" "$PRGNAM"
        exit 0
    fi
else
    printf "[${CYAN}INFO${RESET}] BleachBit is not currently installed.\n"
fi

printf "Current: ${YELLOW}${MYVER:-None}${RESET} | Available: ${GREEN}%s${RESET}\n" "$VERSION"
read -r -p "Build ${PRGNAM} ${GREEN}${VERSION}${RESET} xzm module? [y/N]: " -n 1 -s && echo
[[ ! $REPLY =~ ^[Yy]$ ]] && { printf "Build cancelled.\n"; exit 0; }

rm -rf "$TMPDIR"
mkdir -p "$SRC" "$PKG/usr/bin" "$PKG/usr/share/applications" "$OUTPUT"
cd "$TMPDIR" || exit 1

printf "\nDownloading %s%s%s${RESET}\n" "$CYAN" "$BOLD" "bleachbit-${TAG}.tar.gz"

if command -v wget >/dev/null 2>&1; then
    wget -q "$SOURCE" -O "$TMPDIR/$PRGNAM.tar.gz" || { printf "${RED}Download failed.${RESET}\n"; exit 1; }
elif command -v curl >/dev/null 2>&1; then
    curl -fsL --max-time 120 "$SOURCE" -o "$TMPDIR/$PRGNAM.tar.gz" || { printf "${RED}Download failed.${RESET}\n"; exit 1; }
else
    printf "${RED}Neither wget nor curl is available.${RESET}\n"
    exit 1
fi

tar -xf "$TMPDIR/$PRGNAM.tar.gz" -C "$SRC" --strip-components=1 || { printf "${RED}Failed to extract.${RESET}\n"; exit 1; }
rm -f "$TMPDIR/$PRGNAM.tar.gz"

[[ -f "$SRC/Makefile" && -f "$SRC/bleachbit.py" ]] || { printf "${RED}Source validation failed.${RESET}\n"; exit 1; }

cd "$SRC" || exit 1

printf "Building translations...\n"
make -s -C po local >/dev/null 2>&1 || { printf "${RED}Failed to build translations.${RESET}\n"; exit 1; }

printf "Installing to package directory...\n"
make -s install DESTDIR="$PKG" prefix=/usr >/dev/null 2>&1 || { printf "${RED}Installation failed.${RESET}\n"; exit 1; }

[[ -f "$PKG/usr/bin/bleachbit" ]] || { printf "${RED}Build failed: bleachbit binary not found.${RESET}\n"; exit 1; }

setup_locale() {
    local ldir="$PKG/usr/share/locale"
    [[ ! -d "$ldir" ]] && return 0

    local locales=($(find "$ldir" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' 2>/dev/null | sort))
    local count=${#locales[@]}
    [[ "$count" -eq 0 ]] && return 0

    printf "\n${CYAN}BleachBit locale setup${RESET}\n"
    printf "Available locales (%s):\n" "$count"

    local COLS=5
    local ROWS=$(( (count + COLS - 1) / COLS ))

    for ((i=0; i<ROWS; i++)); do
        for ((j=0; j<COLS; j++)); do
            local idx=$((i + j * ROWS))
            if [ "$idx" -lt "$count" ]; then
                printf "  %2d) %-15s" "$((idx + 1))" "${locales[$idx]}"
            fi
        done
        echo
    done

    local choice
    while true; do
        echo
        read -r -p "Locale number to keep (English always kept) [1-$count, Enter=English only]: " choice

        if [ -z "$choice" ]; then
            find "$ldir" -mindepth 1 -maxdepth 1 -type d -not -name "en*" -exec rm -rf {} +
            printf "${GREEN}info: only English kept${RESET}\n"
            return 0
        fi

        if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$count" ]; then
            break
        fi

        printf "${RED}warn: invalid input, try again.${RESET}\n"
    done

    local target="${locales[$((choice-1))]}"
    printf "  -> Locale set to: ${GREEN}%s${RESET} (English also kept)\n" "$target"
    find "$ldir" -mindepth 1 -maxdepth 1 -type d -not -name "en*" -not -name "$target" -exec rm -rf {} +
}

setup_locale

printf "\n${CYAN}Cleaning up unnecessary files...${RESET}\n"

BB_SHARE="$PKG/usr/share/bleachbit"
CLEANERS="$BB_SHARE/cleaners"

printf "  -> Removing Windows-specific cleaners...\n"
rm -f "$CLEANERS/internet_explorer.xml" \
      "$CLEANERS/windows_explorer.xml" \
      "$CLEANERS/microsoft_office.xml" \
      "$CLEANERS/smartftp.xml" \
      "$CLEANERS/tortoisesvn.xml" \
      "$CLEANERS/wordpad.xml"
rm -f "$CLEANERS"/win*.xml

printf "  -> Removing Windows-specific Python modules and bytecode...\n"
rm -f "$BB_SHARE/Winapp.py" "$BB_SHARE"/Windows*.py
find "$BB_SHARE/__pycache__" -maxdepth 1 -type f \
    \( -name 'Winapp.*' -o -name 'Windows.*' -o -name 'WindowsWipe.*' \) \
    -delete 2>/dev/null

printf "  -> Removing documentation and metadata...\n"
rm -rf "$PKG/usr/share/doc" \
       "$PKG/usr/share/man" \
       "$PKG/usr/share/metainfo" \
       "$PKG/usr/share/icons" \
       "$PKG/usr/include"

printf "  -> Removing text files and tests...\n"
rm -f "$BB_SHARE"/README* \
      "$BB_SHARE"/COPYING* \
      "$BB_SHARE"/NEWS* \
      "$BB_SHARE"/AUTHORS* \
      "$BB_SHARE"/THANKS* \
      "$BB_SHARE"/ChangeLog* \
      "$BB_SHARE"/CHANGES* \
      "$BB_SHARE"/LICENSE*
rm -rf "$BB_SHARE/tests"
find "$PKG/usr/lib" -type d -path '*bleachbit*/tests' -exec rm -rf {} + 2>/dev/null

printf "  -> Removing optimized Python bytecode...\n"
find "$PKG" -type f -name "*.opt-*.pyc" -delete 2>/dev/null

printf "  -> Removing empty directories...\n"
find "$PKG" -mindepth 1 -type d -empty -delete 2>/dev/null

printf "  -> Fixing desktop icon path...\n"
desktop_file="$PKG/usr/share/applications/org.bleachbit.BleachBit.desktop"
if [[ -f "$desktop_file" ]]; then
    sed -i \
        -e 's|^Icon=bleachbit$|Icon=/usr/share/pixmaps/bleachbit.png|' \
        -e 's|^Icon=org.bleachbit.BleachBit$|Icon=/usr/share/pixmaps/bleachbit.png|' \
        "$desktop_file"
fi

printf "  -> Generating metadata...\n"
cd "$PKG" || exit 1
mkdir -p "$PKGINFO"

{
    printf "PACKAGE NAME: %s-%s-%s\n" "$PRGNAM" "$VERSION" "$ARCH"
    printf "PACKAGE DESCRIPTION:\n"
    printf "bleachbit: BleachBit (system cleaner and privacy tool)\n"
    printf "bleachbit: Frees disk space and maintains privacy.\n"
    printf "bleachbit: Homepage: https://www.bleachbit.org/\n"
    printf "FILE LIST:\n"
    find . -type f ! -path './var/*' -printf '%P\n' | sort
} > "$PKGINFO/${PRGNAM}-${VERSION}-${ARCH}"

printf "\n${CYAN}Building XZM module...${RESET}\n"
FINAL_MODULE="$OUTPUT/${PRGNAM}-${VERSION}-${ARCH}-${BUILD}.xzm"
rm -f "$FINAL_MODULE"

if ! dir2xzm "$PKG" "$FINAL_MODULE" >/dev/null 2>&1; then
    printf "\n${RED}${BOLD}[FAIL] Failed to build the module.${RESET}\n\n"
    exit 1
fi

if [ -f "$FINAL_MODULE" ]; then
    MODULE_SIZE=$(du -h "$FINAL_MODULE" | cut -f1)
    printf "\n${BOLD}[OK] Module successfully created!${RESET}\n"
    printf "${BOLD}Location: ${GREEN}%s${RESET}\n" "$FINAL_MODULE"
    printf "${BOLD}Size: ${CYAN}%s${RESET}\n" "$MODULE_SIZE"
    printf "${BOLD}Action: Copy it to your /porteus/modules folder to survive a reboot.${RESET}\n\n"
else
    printf "\n${RED}${BOLD}[FAIL] Failed to build the module.${RESET}\n\n"
    exit 1
fi
