#!/bin/bash
# Author: Tomas M. <http://www.slax.org/>
# Author: crims0n <https://minios.dev>

VERSION="1.0"
BEXT="sb"
COMP_TYPE="zstd"
export TEXTDOMAIN="minios-tools"

help() {
    echo "$(gettext "Usage"): $(basename $0) [OPTIONS]... SOURCE_DIRECTORY [TARGET_FILE]"
    echo "$(gettext "Converts a directory to a compressed .sb module")"
    echo ""
    echo "$(gettext "Options"):"
    echo "  -b, --bext EXT              $(gettext "Bundle extension. Default: sb")"
    echo "  -c, --comp TYPE             $(gettext "Compression type (zstd, gzip, lzo, xz). Default: zstd")"
    echo "      --help                  $(gettext "Display this help and exit")"
    echo "      --version               $(gettext "Display version information and exit")"
    echo ""
    echo "$(gettext "Arguments"):"
    echo "  SOURCE_DIRECTORY            $(gettext "The directory to convert to a module")"
    echo "  TARGET_FILE                 $(gettext "Optional. The name of the output module file")"
    echo ""
    echo "$(gettext "Behavior"):"
    echo "  * $(gettext "If SOURCE_DIRECTORY does not have a .sb extension and is not 'squashfs-root', then the directory itself is included in the module, and TARGET_FILE is required.")"
    echo "  * $(gettext "If TARGET_FILE is not specified, SOURCE_DIRECTORY is replaced by the new module file.")"
    exit 0
}

brief_help() {
    echo "$(gettext "Usage"): $(basename $0) [OPTIONS]... SOURCE_DIRECTORY [TARGET_FILE]"
    echo "$(gettext "Try") '$(basename $0) --help' $(gettext "for more information.")"
    exit 1
}

version() {
    echo "$(basename $0) $VERSION"
    exit 0
}

while [ $# -gt 0 ]; do
    case "$1" in
    -b | --bext)
        BEXT="$2"
        shift 2
        ;;
    -c | --comp)
        COMP_TYPE="$2"
        shift 2
        ;;
    --help)
        help
        ;;
    --version)
        version
        ;;
    *)
        if [ "$1" == -* ]; then
            brief_help
        fi
        POSARGS+=("$1")
        shift
        ;;
    esac
done

if [ "$(id -u)" != "0" ]; then
    echo "This script must be run as root."
    brief_help
fi

if [ ${#POSARGS[@]} -eq 0 ]; then
    brief_help
elif [ ${#POSARGS[@]} -gt 2 ]; then
    brief_help
fi

P1="$(readlink -f "${POSARGS[0]}")"
if [ ${#POSARGS[@]} -eq 2 ]; then
    P2="$(readlink -f "${POSARGS[1]}")"
else
    P2=""
fi

if [ "$P1" = "$P2" ]; then
    P2=""
fi

SB=$(echo "$P1" | grep -o "[.]sb/*\$")
if [ "$(echo "$P1" | grep -o "/squashfs-root/*\$")" != "" ]; then
    SB="true"
fi

if [ "$SB" = "" ]; then
    KEEP="-keep-as-directory"
    if [ "$P2" = "" ]; then
        brief_help
    fi
else
    KEEP=""
fi

if [ ! -d "$P1" ]; then
    echo "Not a directory: $P1" >&2
    exit 2
fi

if [ "$COMP_TYPE" = "zstd" ]; then
    COMP_OPTS="-Xcompression-level 19"
elif [ "$COMP_TYPE" = "xz" ]; then
    COMP_OPTS="-Xbcj x86"
else
    COMP_OPTS=""
fi

if [ "$P2" = "" ]; then
    TARGET="$P1.$BEXT"
    while [ -e "$TARGET" ]; do TARGET="$TARGET"x; done
else
    TARGET="$P2"
    if [ -e "$TARGET" ]; then
        echo "Target exists: $TARGET" >&2
        exit 4
    fi
fi

MKSQUASHFS_CMD="mksquashfs $P1 $TARGET -comp $COMP_TYPE -b 1024K -always-use-fragments -quiet $COMP_OPTS"
if [ "$KEEP" = "-keep-as-directory" ]; then
    MKSQUASHFS_CMD="$MKSQUASHFS_CMD -keep-as-directory"
fi

$MKSQUASHFS_CMD || exit 5

if [ "$P2" = "" ]; then
    umount "$P1" 2>/dev/null
    rm -Rf "$P1"
    mv "$TARGET" "$P1"
fi
