#!/bin/bash

print_color() {
	local color_code="$1"
	local text="$2"
	echo -e "\033[${color_code}m${text}\033[0m"
}

COLOR_YELLOW="33"
COLOR_GREEN="32"
COLOR_RED="31"
COLOR_BLUE="34"

if ! [ "$(whoami)" == "root" ]; then
	print_color $COLOR_RED "✘ Error: This script must be run as root."
	exit 1
fi

LIBC=$(ldd --version 2>&1 | awk '/GNU libc/ {print "glibc"} /musl/ {print "musl"}')
ARCH=$(uname -m)

if [ "$ARCH" == "aarch64" ]; then
	ARCH="arm64"
elif [ "$ARCH" == "x86_64" ]; then
	ARCH="amd64"
fi

DATE=$(date +%Y%m%d)

# Default build type is empty (for normal tarballs)
BUILD_TYPE=""
BUILD_TYPE_SUFFIX=""
USAGE="Usage:\n\
	$(basename $0) [-q -c] [-b <default|desktop|debug>] [-s || -t <target-mountpoint>] [custom-tar-options]\n\
	-b: build type suffix (default, desktop, debug)\n\
	-q: activates quiet mode (no confirmation).\n\
	-s: makes tarball of current system.\n\
	-t: makes tarball of system located at the <target-mountpoint>.\n\
	-h: displays help message."

QUIET=0

while getopts ':t:skqhb:' flag; do
	case "${flag}" in
		t)
			TARGET="$OPTARG"
			;;
		s)
			TARGET="/"
			;;
		q)
			QUIET=1
			;;
		b)
			BUILD_TYPE="$OPTARG"
			;;
		h)
			echo -e "$USAGE"
			exit 0
			;;
		\?)
			print_color $COLOR_RED "✘ Invalid option: -$OPTARG"
			exit 1
			;;
		:)
			print_color $COLOR_RED "✘ Option -$OPTARG requires an argument."
			exit 1
			;;
	esac
done

# Determine suffix
case "$BUILD_TYPE" in
	""|"default")
		BUILD_TYPE_SUFFIX=""
		;;
	"desktop")
		BUILD_TYPE_SUFFIX="-desktop"
		;;
	"debug")
		BUILD_TYPE_SUFFIX="-debug"
		;;
	*)
		print_color $COLOR_RED "✘ Error: Unknown build type: $BUILD_TYPE"
		echo -e "$USAGE"
		exit 1
		;;
esac

ARCHIVE="1g4-${LIBC}-${ARCH}-${DATE}${BUILD_TYPE_SUFFIX}.tar.xz"
STAGE3_FILENAME="$(pwd)/${ARCHIVE}"

if [ -z "$TARGET" ]; then
	print_color $COLOR_RED "✘ Error: No target specified."
	echo -e "$USAGE"
	exit 1
fi

if [ "$(echo "$TARGET" | grep -c '/$')" -le 0 ]; then
	TARGET="${TARGET}/"
fi

if [ -f "$STAGE3_FILENAME" ]; then
	if [ "$QUIET" -ne 1 ]; then
		print_color $COLOR_YELLOW "⚠️  Warning: File '$STAGE3_FILENAME' already exists."
		read -p "$(print_color $COLOR_YELLOW 'Do you want to overwrite it? [y/N]: ')" OVERWRITE
		if [[ "$OVERWRITE" != "y" && "$OVERWRITE" != "Y" ]]; then
			print_color $COLOR_RED "✘ Aborting."
			exit 1
		else
			print_color $COLOR_GREEN "✔ Overwriting the existing file..."
		fi
	else
		print_color $COLOR_GREEN "✔ Overwriting existing file $STAGE3_FILENAME"
	fi
fi

EXCLUDES="--exclude=${TARGET}boot/*
	--exclude=${TARGET}dev/*
	--exclude=${TARGET}etc/.pwd.lock
	--exclude=${TARGET}etc/config-archive
	--exclude=${TARGET}etc/localtime
	--exclude=${TARGET}etc/mtab
	--exclude=${TARGET}etc/qemu
	--exclude=${TARGET}etc/resolv.conf
	--exclude=${TARGET}etc/ssh/*{key,pub}
	--exclude=${TARGET}etc/.updated
	--exclude=${TARGET}etc/*-
	--exclude=${TARGET}home/*
	--exclude=${TARGET}usr/lib/modules/*
	--exclude=${TARGET}lost+found
	--exclude=${TARGET}media/*
	--exclude=${TARGET}mnt/*
	--exclude=${TARGET}opt/*
	--exclude=${TARGET}proc/*
	--exclude=${TARGET}root/*
	--exclude=${TARGET}run/*
	--exclude=${TARGET}sys/*
	--exclude=${TARGET}tmp/*
	--exclude=${TARGET}usr/distfiles
	--exclude=${TARGET}usr/packages
	--exclude=${TARGET}usr/portage
	--exclude=${TARGET}usr/share/doc
	--exclude=${TARGET}usr/share/gtk-doc
	--exclude=${TARGET}usr/share/man
	--exclude=${TARGET}usr/src/*
	--exclude=${TARGET}var/cache/binpkgs/*
	--exclude=${TARGET}var/cache/distfiles/*
	--exclude=${TARGET}var/cache/edb/*
	--exclude=${TARGET}var/cache/ldconfig/*
	--exclude=${TARGET}var/cache/man/*
	--exclude=${TARGET}var/cache/packages/*
	--exclude=${TARGET}var/cache/private/*
	--exclude=${TARGET}var/db/repos/*
	--exclude=${TARGET}var/lib/connman
	--exclude=${TARGET}var/lib/dbus/*
	--exclude=${TARGET}var/lib/portage/world
	--exclude=${TARGET}var/lock/*
	--exclude=${TARGET}var/log/*
	--exclude=${TARGET}var/run/*
	--exclude=${TARGET}var/tmp/*"

# Place for further variant customization
case "$BUILD_TYPE" in
	"desktop")
		# e.g. Uncomment and customize if you want to change EXCLUDES for desktop
		# EXCLUDES+=" --exclude=${TARGET}some-desktop-thing"
		;;
	"debug")
		# e.g. Uncomment and customize if you want to change EXCLUDES for debug
		# EXCLUDES+=" --exclude=${TARGET}some-debug-thing"
		;;
esac

if [ "$TARGET" == "/" ]; then
	EXCLUDES+=" --exclude=/${STAGE3_FILENAME#/}"
fi

if [ ${QUIET} -ne 1 ]; then
	print_color $COLOR_BLUE "ℹ️  Creating tarball with the following filename:"
	print_color $COLOR_GREEN "$STAGE3_FILENAME"
	read -p "$(print_color $COLOR_YELLOW 'Are you sure you want to proceed? [y/N]: ')" CONFIRM
	if [[ "$CONFIRM" != "y" && "$CONFIRM" != "Y" ]]; then
		print_color $COLOR_RED "✘ Aborting."
		exit 1
	else
		print_color $COLOR_GREEN "✔	Proceeding with tarball creation..."
	fi
fi

print_color $COLOR_BLUE "ℹ️	Preparing system for tarball creation..."
rm -f ${TARGET}etc/machine-id && touch ${TARGET}etc/machine-id

mkdir -p ${TARGET}var/log/journal
mkdir -p ${TARGET}var/empty
mkdir -p ${TARGET}etc/ssh
mkdir -p ${TARGET}run/lock

chmod -R 600 ${TARGET}var/empty
chmod -R 600 ${TARGET}etc/ssh

CPU_CORES=$(nproc)
print_color $COLOR_BLUE "ℹ️	Starting compression with xz (using $CPU_CORES cores)..."
XZ_OPT="--x86 --delta=dist=2 --lzma2=dict=128Mi -e9 -T${CPU_CORES}" tar -cJ --ignore-failed-read $EXCLUDES -f $STAGE3_FILENAME ${TARGET}*

print_color $COLOR_GREEN "✔	Tarball creation completed successfully."

exit 0
