#!/bin/bash
# info: add file manager functionality to Tulio Control Panel
# options: [MODE]
#
# This function installs the File Manager on the server
# for access through the Web interface.

#----------------------------------------------------------#
#                Variables & Functions                     #
#----------------------------------------------------------#

# Includes
# shellcheck source=/etc/tuliocp/tulio.conf
source /etc/tuliocp/tulio.conf
# shellcheck source=/usr/local/tulio/func/main.sh
source "$TULIO/func/main.sh"
# load config file
source_conf "$TULIO/conf/tulio.conf"
# load config file
source_conf "$TULIO/install/upgrade/upgrade.conf"

MODE="$1"
user="$ROOT_USER"

FM_INSTALL_DIR="$TULIO/web/fm"
FM_FILE="filegator_v${fm_v}"
FM_URL="https://github.com/filegator/static/raw/master/builds/${FM_FILE}.zip"
COMPOSER_BIN="$HOMEDIR/$user/.composer/composer"

#----------------------------------------------------------#
#                    Verifications                         #
#----------------------------------------------------------#

# Checking root permissions
if [[ "x$(id -u)" != 'x0' ]]; then
	echo "ERROR: v-add-sys-filemanager can only be executed by the root user" >&2
	"$BIN/v-log-action" "system" "Error" "Plugins" "File Manager installation failed: root privileges required (Version: $fm_v)."
	exit 10
fi

if [[ -z "$HOMEDIR" || -z "$TULIO_INSTALL_DIR" ]]; then
	echo "ERROR: Environment variables not present, installation aborted." >&2
	"$BIN/v-log-action" "system" "Error" "Plugins" "File Manager installation failed: required environment variables are missing (Version: $fm_v)."
	exit 2
fi

# Ensure that Composer is installed for the user before continuing as it is a dependency of the File Manager.
if [[ ! -f "$COMPOSER_BIN" ]]; then
	"$BIN/v-add-user-composer" "$user"
	if [[ $? -ne 0 ]]; then
		echo "ERROR: Composer installation failed!" >&2
		"$BIN/v-add-user-notification" "$ROOT_USER" 'Composer installation failed!' '<p class="u-text-bold">The File Manager will not work without Composer.</p><p>Please try running the installer manually from a shell session:<br><code>v-add-sys-filemanager</code></p><p>If this continues, <a href="https://github.com/marcosfermin/tuliocp/issues" target="_blank">open an issue on GitHub</a>.</p>'
		"$BIN/v-log-action" "system" "Error" "Plugins" "File Manager installation failed: Composer installation failed (Version: $fm_v)."
		exit 1
	fi
fi

# Perform verification if read-only mode is enabled
check_tulio_demo_mode

#----------------------------------------------------------#
#                       Action                             #
#----------------------------------------------------------#

openssl_installed=$(/usr/local/tulio/php/bin/php -m | grep openssl)

# Download and verify package in a temporary directory, without touching FM_INSTALL_DIR yet
FM_TMP_DIR=$(mktemp -d)
trap 'rm -rf "$FM_TMP_DIR"' EXIT
FM_ZIP="${FM_TMP_DIR}/${FM_FILE}.zip"

wget "$FM_URL" --quiet -O "$FM_ZIP"

# Check that the file exists and is not 0 bytes
if [[ ! -s "$FM_ZIP" ]]; then
	echo "ERROR: File Manager download failed or the downloaded file is empty!" >&2
	"$BIN/v-add-user-notification" "$ROOT_USER" 'File Manager installation failed!' '<p>Package download failed or file is empty.</p>'
	"$BIN/v-log-action" "system" "Error" "Plugins" "File Manager installation failed: package download failed or file is empty (Version: $fm_v)."
	exit 1
fi

# Check that it is actually a valid zip file (not just that it has the extension)
if ! unzip -tqq "$FM_ZIP" > /dev/null 2>&1; then
	echo "ERROR: Downloaded File Manager package is not a valid zip file!" >&2
	"$BIN/v-add-user-notification" "$ROOT_USER" 'File Manager installation failed!' '<p>Downloaded package is not a valid ZIP file.</p>'
	"$BIN/v-log-action" "system" "Error" "Plugins" "File Manager installation failed: downloaded package is not a valid ZIP file (Version: $fm_v)."
	exit 1
fi

# We only get here if the downloaded package is valid: now it's safe to clean up
rm -rf "$FM_INSTALL_DIR"
mkdir -p "$FM_INSTALL_DIR"

if ! unzip -qq "$FM_ZIP" -d "$FM_INSTALL_DIR"; then
	echo "ERROR: Failed to extract File Manager package!" >&2
	"$BIN/v-add-user-notification" "$ROOT_USER" 'File Manager installation failed!' '<p>Package extraction failed.</p>'
	"$BIN/v-change-sys-config-value" 'FILE_MANAGER' 'false'
	"$BIN/v-log-action" "system" "Error" "Plugins" "File Manager installation failed: package extraction failed (Version: $fm_v)."
	rm -rf "$FM_INSTALL_DIR"
	exit 1
fi

if [[ ! -d "${FM_INSTALL_DIR}/filegator" ]]; then
	echo "ERROR: Unexpected package structure, 'filegator' directory not found!" >&2
	"$BIN/v-add-user-notification" "$ROOT_USER" 'File Manager installation failed!' '<p>Unexpected package structure.</p>'
	"$BIN/v-change-sys-config-value" 'FILE_MANAGER' 'false'
	"$BIN/v-log-action" "system" "Error" "Plugins" "File Manager installation failed: unexpected package structure (Version: $fm_v)."
	rm -rf "$FM_INSTALL_DIR"
	exit 1
fi

mv -f "${FM_INSTALL_DIR}"/filegator/* "${FM_INSTALL_DIR}"
rm -rf "${FM_INSTALL_DIR}/filegator"
cp -rf "${TULIO_INSTALL_DIR}"/filemanager/filegator/* "${FM_INSTALL_DIR}"
chown "$user": -R "${FM_INSTALL_DIR}"

if [[ -z "$openssl_installed" ]]; then
	COMPOSER_HOME="$HOMEDIR/$user/.config/composer" user_exec /usr/bin/php "$COMPOSER_BIN" --working-dir="$FM_INSTALL_DIR" --quiet --no-dev install
else
	COMPOSER_HOME="$HOMEDIR/$user/.config/composer" user_exec /usr/local/tulio/php/bin/php "$COMPOSER_BIN" --working-dir="$FM_INSTALL_DIR" --quiet --no-dev install
fi

# Check if installation was successful, if not abort script and throw error message notification and clean-up
if [[ $? -ne 0 ]]; then
	echo "ERROR: Composer dependency installation failed!" >&2
	"$BIN/v-add-user-notification" "$ROOT_USER" 'File Manager installation failed!' '<p>Composer dependency installation failed.</p>'
	# Installation failed, clean up files
	"$BIN/v-change-sys-config-value" 'FILE_MANAGER' 'false'
	"$BIN/v-log-action" "system" "Error" "Plugins" "File Manager installation failed: Composer dependency installation failed (Version: $fm_v)."
	rm -rf "${FM_INSTALL_DIR}"
	exit 1
fi

# Add configuration file
cp -f "$TULIO_INSTALL_DIR/filemanager/filegator/configuration.php" "$TULIO/web/fm/configuration.php"

# Path to the file manager configuration file where the change will be made.
config_file="$TULIO/web/fm/configuration.php"
app_name="File Manager - $APP_NAME"

# Sed replaces only the value after "File Manager -"
sed -i "s|\(\$dist_config\[\"frontend_config\"\]\[\"app_name\"\] = \"File Manager - \).*\";|\1${APP_NAME}\";|" "$config_file"

echo "$fm_v" > "${FM_INSTALL_DIR}/version"
# Set permissions
chown root: -R "${FM_INSTALL_DIR}"
chown tulioweb: "${FM_INSTALL_DIR}/private"
chown tulioweb: "${FM_INSTALL_DIR}/private/logs"
chown tulioweb: "${FM_INSTALL_DIR}/repository"

"$BIN/v-change-sys-config-value" 'FILE_MANAGER' 'true'

# Apply SSH config if running on Debian 13
source /etc/os-release
if [[ "$ID" == "debian" && "$VERSION_ID" == "13" ]]; then
	_KEX_CONF="/etc/ssh/sshd_config.d/tulio-kex.conf"
	_KEX_LINE="KexAlgorithms +diffie-hellman-group-exchange-sha256"

	# Only create/modify the file if it doesn't already contain the correct config
	if [[ ! -f "$_KEX_CONF" ]] || ! grep -qxF "$_KEX_LINE" "$_KEX_CONF"; then
		echo "$_KEX_LINE" > "$_KEX_CONF"
		"$BIN/v-restart-service" ssh
	fi
fi

#----------------------------------------------------------#
#                       Logging                            #
#----------------------------------------------------------#

"$BIN/v-log-action" "system" "Info" "Plugins" "File Manager enabled (Version: $fm_v)."
log_event "$OK" "$ARGUMENTS"
