#!/bin/bash

MODULE_FILE="$(dirname $0)/../modules.mk"
TMP_MOD="modules.tmp"
QUIET=0

if [ -z "${SULU_BRANCH}" ]; then
	if [ -n "${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}" ]; then
		SULU_BRANCH="${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}"
	elif [ -n "${CI_COMMIT_BRANCH}" ]; then
		SULU_BRANCH="${CI_COMMIT_BRANCH}"
	else
		SULU_BRANCH="${CI_DEFAULT_BRANCH}"
	fi
fi

function log() {
	[ "$QUIET" -eq 1 ] || echo "$*"
}

function exec_cmd() {

	[ "${QUIET}" -eq "1" ] || echo "Running $@"

	if ! $@ > /dev/null 2>&1; then
		echo "Failed running $@"
		exit 1;
	fi
}

function update() {
	local name version

	name="${1}"
	version="${2}"

	if [ -n "${CI_DEFAULT_BRANCH}" ]; then
		exec_cmd git -C $name checkout "${CI_DEFAULT_BRANCH}"
	else
		exec_cmd git -C $name checkout devel
	fi
	exec_cmd git -C $name pull --rebase
	exec_cmd git -C $name checkout $version
}

function clone() {
	local url name version

	url="${1}"
	name="${2}"
	version="${3}"

	if [ -d "$name" ]; then
		log "$name already present, running update"
		update "${name}" "${version}"
	else
		if [ -n "${CI_JOB_TOKEN}" ]; then
			exec_cmd git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@$url $name
		else
			exec_cmd git clone git@${url/\//:} $name
		fi
		exec_cmd git -C $name checkout $version
	fi
}

function pull_module() {
	local line url name version tmp

	url="${2}"
	url="$(echo ${url/https:\/\//})"
	tmp="$(basename $url)"
	name="${1}/${tmp/.git/}"
	version="${3}"

	clone "$url" "$name" "$version"
}

function pull_uppdates() {
	local line url name version tmp

	url="${2}"
	url="$(echo ${url/https:\/\//})"
	tmp="$(basename $url)"
	name="${1}/${tmp/.git/}"
	version="${3}"

	update "$name" "$version"
}

function update_module() {
	local url name version

	version=""
	name="${1}"
	url="${2}"
	url="${url/https:\/\//}"
	url="${url/http:\/\//}"
	url="git@${url/\//:}"

	version="$(git ls-remote --heads $url ${SULU_BRANCH})"
	version="$(echo $version|awk '{printf $1}')"
	if [ -z "${version}" ]; then
		echo "Failed to get SHA1 for $url"
		exit 7
	fi

	echo "$name ${2} $version" >>${TMP_MOD}
}

function pull_modules() {
	local line

	if [ -z "${CI_JOB_TOKEN}" ]; then
		log "Using ssh credentials for pulling the plugins"
	fi

	while read -r line
	do
		pull_module $line
	done < "${MODULE_FILE}"
}

function update_modules() {
	local line

	if [ -z "${CI_JOB_TOKEN}" ]; then
		log "Using ssh credentials for pulling the plugins"
	fi

	while read -r line
	do
		pull_uppdates $line
	done < "${MODULE_FILE}"
}

function fix_modules() {
	local line url

	if [ -f "${TMP_MOD}" ]; then
		exec_cmd rm -f ${TMP_MOD}
	fi

	log "# SULU Base Branch ${SULU_BRANCH} #"
	while read -r line
	do
		update_module $line
	done < "${MODULE_FILE}"
	exec_cmd mv ${TMP_MOD} ${MODULE_FILE}
}

function print_help() {
	echo "$0 script to manage sulu modules for CI pipeline"
	echo "Usage"
	echo "  @0 <cmd>"
	echo
	echo "Options:"
	echo "  pull	Pull sulu modules in current directory defined in ${MODULE_FILE}"
	echo "  bump	Update sulu modules version in ${MODULE_FILE}"
	echo "  tar	Create a tar release for sulu"
	echo
}

function tar_release()
{
	COMMITHASH=$(git rev-parse HEAD)
	FILENAME="sulu-builder-$COMMITHASH.tar.gz"
	PKG_DIRECTORY="sulu-builder-$COMMITHASH"

	[ -d "${PKG_DIRECTORY}" ] && rm -rf ${PKG_DIRECTORY}
	# Include pre-built sulu assets
	mkdir -p ${PKG_DIRECTORY}/dist/presets
	mkdir -p ${PKG_DIRECTORY}/dist/settings
	mkdir -p ${PKG_DIRECTORY}/dist/widget-presets
	cp -R ./build/dist/* ./${PKG_DIRECTORY}/dist/
	cp ./build/device/presets/*.json ./${PKG_DIRECTORY}/dist/presets/
	cp ./build/device/settings/*.json ./${PKG_DIRECTORY}/dist/settings/
	cp ./build/device/widget-presets/*.json ./${PKG_DIRECTORY}/dist/widget-presets/

	# Include builder as well
	exec_cmd rsync -av --include=src/libs/build --exclude={'.git/','build/','node_modules/','plugins/','core/',"${PKG_DIRECTORY}/"} ./ ${PKG_DIRECTORY}/

	exec_cmd tar -zcvf $FILENAME ${PKG_DIRECTORY}
}

function change_log() {
	local repo url rev old_rev new_rev change name

	QUIET=1
	update_modules

	change="$(git diff modules.mk |tail -n +6)"
	printf %s "$change" | while read -r repo url rev; do
		if [[ "$repo" == "-"* ]]; then
			old_rev=$rev
			continue
		elif [[ "$repo" == "+"* ]]; then
			new_rev=$rev
		else
			old_rev=""
			new_rev=""
		fi

		if [ -n "$new_rev" ]; then
			repo="${repo/+/}"
			name="$(basename $url)"
			name="${name/.git/}"
			echo "$name:"
			git -C "$repo/$name" log $old_rev...$new_rev --oneline --no-decorate --no-color --line-prefix=" - "
		fi

	done
}

function commit_changes()
{
	local logs ans commit

	commit=0
	logs="$(change_log)"

	if [ -n "$logs" ]; then
		logs="Multiple Updates"$'\n'$'\n'${logs}
		echo "${logs}"
		echo
		echo -n "Do you want to commit these updates? [y/N]"
		read ans

		case "$ans" in
			y*|Y*)
				commit=1;;
		esac

		if [ "$commit" -eq "1" ]; then
			git add .
			git commit -m "${logs}"
		fi
	fi
}

if [ "$1" = "pull" ]; then
	pull_modules
elif [ "$1" = "update" ]; then
	update_modules
elif [ "$1" = "commit" ]; then
	commit_changes
elif [ "$1" = "bump" ]; then
	fix_modules
elif [ "$1" = "tar" ]; then
	tar_release
else
	print_help
	exit 3
fi
