#!/bin/bash

## Copyright (C) 2024, 2025 Ajrat Makhmutov <rauty@altlinux.org>
##
## This file is part of alterator-kopidel.
##
## alterator-kopidel is free software: you can redistribute it and/or modify it under the terms
## of the GNU General Public License as published by the Free Software Foundation,
## either version 3 of the License, or (at your option) any later version.
##
## alterator-kopidel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
## without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
## See the GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License along with alterator-kopidel.
## If not, see <https://www.gnu.org/licenses/>.

. alterator-sh-functions
. /usr/lib/alterator-kopidel/kopidel-steps

if [ "$BOOT_MODE" == UEFI ]; then
	in_grub_device=efi
else
	in_grub_device=root_dev
fi

while [[ $# -gt 0 ]]; do case "$1" in
	-X | --ignored-from)
		in_ignored_files="$2"
		shift # past argument
		shift # past value
	;;
	--xz)
		in_compress_copied='#t'
		shift # past argument
	;;
	-O | --oem-mode)
		in_oem_mode='#t'
		shift # past argument
	;;
	-g | --grub-device)
		in_grub_device="$2"
		shift # past argument
		shift # past value
	;;
	--list-grub-devices)
		echo $(_ "List of available GRUB devices:")
		alterator-cmdline /grub/devices action list
		exit 0
	;;
	--list-workdirs)
		echo $(_ "List of possible working directories:")
		alterator-cmdline /kopidel action workdirs_list
		exit 0
	;;
	-v | --version)
		rpm -q alterator-kopidel --qf "%{version}\n"
		exit 0
	;;
	-s | --step)
		step="$2"
		shift # past argument
		shift # past value
	;;
	-h | --help)
		echo $(_ 'Creates a "razlivochniy obraz".')
		echo $(_ "Usage: kopidel [Options] workdir")
		echo $(_ '"Workdir" is the path to the working directory where razlivochniy.iso is created. Please check that there is enough disk space available.')
		echo $(_ "The workdir name should be alterator-kopidel-workdir.")
		echo
		echo $(_ "Options:")
		echo "	-X, --ignored-from    $(_ "The path to the file with the list of ignored files")."
		echo "	--xz                  $(_ "Compress the copied file system using xz")."
		echo "	-O, --oem-mode        $(_ "Installation in OEM mode")."
		echo "	-h, --help            $(_ "Display this message")."
		echo "	-v, --version         $(_ "Print version info and exit")."
		echo "	-s, --step            $(_ "Run a specific step instead of all of them")."
		echo "	--list-workdirs       $(_ "Display a list of possible working directories and exit")."
		if [ "$BOOT_MODE" == "UEFI" ]; then
		echo "	--list-grub-devices   $(_ "Display a list of available GRUB devices and exit")."
		echo "	-g, --grub-device     $(_ "Device for installing GRUB. Default:") $in_grub_device."
		fi
		echo
		echo $(_ "Please report any problems to <https://bugzilla.altlinux.org/>")
		exit 0
	;;
	-* | --*)
		echo "$(_ "Unknown option:") $1"
		exit 1
	;;
	*)
		in_workdir="$1"
		shift # past argument
	;;
esac; done

if [ -z "$in_workdir" ]; then
	echo "$(_ "ERROR: the working directory is not specified.")"
	exit 1
fi

if ! alterator-cmdline /kopidel action workdirs_list | grep -qx "name:$(realpath "$in_workdir")"; then
	echo "$(_ "ERROR: The working directory is not in the list of possible directories:")"
	alterator-cmdline /kopidel action workdirs_list
	exit 1
fi

draw_progress_bar_handler() (
	gray_background_color='\e[48;5;235m123'
	yellow_bold_color='\033[1;33m'
	default_color='\033[0m'

	#\U2588 - 1, \U2589 - 7/8, \U258A - 6/8, \U258B - 5/8, \U258C - 4/8, \U258D - 3/8, \U258E - 2/8, \U258F - 1/8
	fullblock=$(echo -e '\u2588')
	utf_ends_blocks=( F E D C B A 9 8 )

	while read -r percentage_line; do
		percentage=$(echo "$percentage_line" | sed 's/^step_progress: //')

		columns=$(tput cols)

		bar_main=""
		bar_end=" $percentage%"

		# 1 - space, 3 - percentage number, 1 - perncentage symbol
		bar_length=$(( columns - 1 - 3 - 1 ))
		bar_one_length=$( echo "scale=3; $bar_length / 100" | bc )

		if [ "$percentage" -ge 100 ]; then
			bar_main=$(printf "%${bar_length}s" | sed "s/ /$fullblock/g")
		else
			bar_end=" $bar_end"
			full_blocks_count=$(echo "$bar_one_length * $percentage / 1" | bc)
			bar_main=$(printf "%${full_blocks_count}s" | sed "s/ /$fullblock/g")
			bar_main+=$(echo -e "\u258${utf_ends_blocks[$(echo "$bar_one_length * $percentage % 1 / 0.125" | bc)]}")
			bar_main+=$(printf "%$(( bar_length - full_blocks_count - 1 ))s")
		fi

		echo -e -n "\r$yellow_bold_color$yellow_background_color$bar_main$default_color$bar_end"
	done
)

step_num=0
step_count=5
run_step_cli_wrapper_bar() {
	(( step_num+=1 ))
	echo "[$(date)] $(_ "Step") $step_num/$step_count: $2"
	run_step "$1" | draw_progress_bar_handler
	rtrn="${PIPESTATUS[0]}"
	echo
	return "$rtrn"
}

trap "tput cnorm" EXIT
tput civis # hide cursor

if [ -n "$step" ]; then
	if [[ " ${STEPS[*]} " =~ " $step " ]] || [[ "$KOPIDEL_DEBUG" == 1 && " ${SUBSTEPS[*]} " =~ " $step " ]]; then
		step_count=1
		run_step_cli_wrapper_bar "$step"
	else
		echo "$(_ "There is no such step:")"" $step." >&2
		echo "$(_ "Steps list:")"" ${STEPS[*]}."
		if [ "$KOPIDEL_DEBUG" == 1 ]; then
			echo "$(_ "Substeps list:")"" ${SUBSTEPS[*]}."
		fi
		exit 1
	fi
else
	rm -rf "$in_workdir"
	mkdir -pv "$in_workdir/image/Metadata"
	cd "$in_workdir" || exit 1

	run_step_cli_wrapper_bar prepare_workdir            "$(_ "Preparing the working directory")" || exit 1
	run_step_cli_wrapper_bar create_copied_fs           "$(_ "Copying the file system")" || exit 1
	run_step_cli_wrapper_bar create_disk_partition_info "$(_ "Generating disk partition information")" || exit 1
	run_step_cli_wrapper_bar create_autoinstall_scm     "$(_ "Creating the autoinstall.scm")" || exit 1
	run_step_cli_wrapper_bar create_system_iso          "$(_ "Creating an ISO image")" || exit 1
fi

tput cnorm # restore cursor

echo "[$(date)] $(_ "Successfully created a razlivochniy obraz")"
