#!/bin/bash

# CONSTANTS

declare -A settings=()
declare -a setting_keys=()
declare -a setting_values=()
LOGOUT_NEEDED=false

# FUNCTIONS

function usage {
	echo "USAGE: $(basename "$0") {UUID} [--key1=value1|--key2=value2|...]"
	echo "provide additional facilities to install gnome-extension based on a UUID name + optional predefined settings"
	echo 'a valid UUID name would be: "runcat@kolesnikov.se"'
	echo 'a valid key/value would be: "--idle-threshold=66"'
	echo "thus, a valid final command would be: "$0" runcat@kolesnikov.se --idle-threshold=66"
}

function parse_options {
	[[ -z ${1:-} || $1 =~ ^- ]] && usage && exit 1
	uuid=$1

	shift 1
	while [[ $# -gt 0 ]]; do
		case "$1" in
			--*)
				local key_value=${1#--}
				local key=$(echo $key_value | cut -d= -f1)
				local value=$(echo $key_value | cut -d= -f2)
				echo ["$key"]="$value"
				settings+=(["$key"]="$value")
				;;
			--help | -h)
				usage
				exit 0
				;;
			*)
				echo "Unknown option: $1"
				usage
				exit 2
				;;
		esac

		shift 1 # Move to the next argument
	done
}

function gnome_version {
	gnome-extensions version | cut -d. -f1
}

function find_extension_by_uuid {
	local page=${2:-1}
	JSON=$(curl -Lfs "https://extensions.gnome.org/extension-query/?search='${uuid}'&page=$page")
	local numpages=$(echo $JSON | jq ".numpages")
	local extension=$(echo $JSON | jq ".extensions[] | select(.uuid==\"$uuid\") ")
	if [[ -z $extension ]]; then
		page=$((page + 1))
		[[ $page -gt $numpages ]] && echo "not found, exiting!" && exit 2
		>&2 echo "not found, trying page #$page..."
		find_extension_by_uuid "$uuid" "$page"
	else
		echo "$extension"
	fi
}

function install_extension {
	if ! gnome-extensions list | grep -q "$uuid"; then
		EXTENSION=$(find_extension_by_uuid "$uuid")

		name=$(echo "$uuid" | sed 's/@//')
		version_tag=$(echo "$EXTENSION" | jq ".shell_version_map.\"$(gnome_version)\".version")
		zip_file="$uuid.zip"
		URL="https://extensions.gnome.org/extension-data/$name.v$version_tag.shell-extension.zip"
		wget -qO "$zip_file" "$URL"

		gnome-extensions install --force "$zip_file"
		rm "$zip_file"
		LOGOUT_NEEDED=true
		# busctl call --timeout 20 --expect-reply=yes --user org.gnome.Shell.Extensions /org/gnome/Shell/Extensions org.gnome.Shell.Extensions InstallRemoteExtension s "$uuid"
	else
		>&2 echo "$uuid already installed!"
	fi
}

function enable_extension {
	status=$(gnome-extensions info $uuid | grep Enabled | cut -d' ' -f4)
	if [[ $status != 'Yes' ]]; then
		gnome-extensions enable $uuid
		>&2 echo $uuid now enabled!
	else
		>&2 echo $uuid already enabled!
	fi
}

function find_settings_schema {
	local gschema_file=$(ls ~/.local/share/gnome-shell/extensions/$uuid/schemas/*.gschema.xml)
	gschema_file=$(basename $gschema_file)
	gschema_file=${gschema_file%.gschema.xml}
	echo $gschema_file
}

function convert_to_gvalue {
	value=$1
	# >&2 echo "original=[$value]"
	if [[ $value =~ true|false ]]; then
		echo "$value"
	elif [[ $value =~ ^[0-9]+$ ]]; then
		echo "$value"
	elif [[ $value =~ ^-?[0-9]+\.[0-9]+$ ]]; then
		echo "double $value"
	else
		echo "'$value'"
	fi
}

function define_settings {
	local found=${#settings[@]}
	if [[ $found -gt 0 ]]; then

		local schema=$(find_settings_schema)

		cd ~/.local/share/gnome-shell/extensions/$uuid/schemas
		override="20_$schema.gschema.override"
		[[ -f $override ]] && cp $override $override.old

		echo "[$schema]" > $override
		for key in "${!settings[@]}"; do
			local value=${settings[$key]}
			value=$(convert_to_gvalue "$value")
			echo "$key=$value" >> $override
		done
		glib-compile-schemas ~/.local/share/gnome-shell/extensions/$uuid/schemas

		if [[ -f $override.old ]] && diff -q $override $override.old > /dev/null; then
			>&2 echo default settings already set!
		else
			>&2 echo "override schema: ~/.local/share/gnome-shell/extensions/$uuid/schemas/$override"
			gnome-extensions disable $uuid
			gnome-extensions reset $uuid
		fi
	fi

}

# MAIN

set -Eue
parse_options $*
install_extension
define_settings
enable_extension
[[ $LOGOUT_NEEDED == true ]] && echo "please logout to take effect!" || true
