#!/bin/bash

usage() {
	cat <<EOF

Usage: xivo-build <project_name> <build_type> <branch_or_tag>
 - <project_name> name of the project to be built.

 - <build_type> is one of
   - dev
        Build & publish to dev distribution (xivo-CODENAME-dev)
   - unstable
        Build & publish to unstable distribution (xivo-CODENAME-unstable)
   - rc
        Build & publish to dev distribution (xivo-VERSION)

 - <branch_or_tag> name of the branch or tag to be built from.

EOF
	exit -1
}

get_dist_target() {
	case ${BUILD_TYPE} in
	dev | unstable)
		echo "${PKG_DISTRIB}-${BUILD_TYPE}" # xivo-electra-dev
		;;

	rc)
		echo "xivo-${XS_VERSION}" # xivo-2019.14.00
		;;
	esac
}

get_repo_target() {
	case ${BUILD_TYPE} in
	dev | unstable)
		echo "debian"
		;;
	rc)
		echo "archive"
		;;
	esac
}

export_variables() {
	echo "DEBIAN_VERSION=$(dpkg-parsechangelog --show-field version)" >INJECT_FILE
	echo "DISTRIBUTION=$(get_dist_target)" >>INJECT_FILE
	echo "REPO=$(get_repo_target)" >>INJECT_FILE
	echo "LTS_CODENAME=${PKG_DISTRIB/xivo-/}" >>INJECT_FILE
}

ensure_git_tag_inexistent() {
	if git rev-parse "${XS_VERSION}" >/dev/null 2>&1; then
		echo "${XS_VERSION} is already tagged, cannot continue."
		echo "Did you forget to update the changelog ?"
		exit -1
	fi
}

ensure_git_and_build_rc_tag_existent() {
	local rc_version="${XS_VERSION}-rc"

	if git rev-parse "${rc_version}" >/dev/null 2>&1 && [ "${BRANCH_OR_TAG}" == "${rc_version}" ]; then
		echo "The RC tag ${BRANCH_OR_TAG} is correct, continue."
	else
		echo "The RC tag (${BRANCH_OR_TAG}) does not correspond to the expected ${rc_version}"
		exit -1
	fi
}

check_changelog_against_tag() {
	if [ "$XS_VERSION" == "$VERSION_FROM_TAG" ]; then
		return 0
	else
		echo "Changelog version ($XS_VERSION) does not match the version tag ($BRANCH_OR_TAG}) this job is building from."
		exit 1
	fi
}

parse_version() {
	echo ${1} | grep -oE '[0-9]{2,4}\.[0-9]+(\.[0-9]+)?|1\.2\.[0-9]{1,2}'
}

check_distribution() {
	local lts_distribs_array=(${LTS_DISTRIBS})
	for dist in "${lts_distribs_array[@]}"; do
		if [[ "${PKG_DISTRIB}" == "${dist}" ]]; then
			return 0
		fi
	done
	echo "Distribution $PKG_DISTRIB not allowed"
	echo "Allowed distributions: $LTS_DISTRIBS"
	exit 10
}

check_version_is_valid() {
	local temp_version=${PKG_VERSION:-"unknown"}

	if [[ ! ${temp_version} =~ [0-9]{4}\.[0-9]{2}\.[0-9]{2} ]]; then
		echo "Version ${temp_version} is not a valid xivo.solutions format"
		echo "Build is not possible"
		exit 11
	fi
}

check_version_and_distribution_consistency() {
	local lts_releases=($(curl --silent "https://mirror.xivo.solutions/version/${PKG_DISTRIB}"))
	local lts_releases_numeric=(${lts_releases[@]/./})
	local release_numeric=${XS_RELEASE/./}

	if [[ ${release_numeric} -ge ${lts_releases_numeric[0]} ]] && [[ ${release_numeric} -le ${lts_releases_numeric[1]} ]]; then
		return 0
	else
		echo "Version ${XS_RELEASE} cannot be built to distribution ${PKG_DISTRIB}"
		echo "Did you forget to update distribution in changelog"
		exit 12
	fi
}

# Beginning of script

if [ -z $1 ]; then
	echo "Required argument missing: <project_name>"
	usage
fi

if [ -z $2 ]; then
	echo "Required argument missing: <build_type>"
	usage
fi

if [ -z $3 ]; then
	echo "Required argument missing: <branch_or_tag>"
	usage
fi

PKG_DISTRIB=$(dpkg-parsechangelog --show-field distribution)
PKG_VERSION=$(parse_version $(dpkg-parsechangelog --show-field version))
BUILD_TYPE=$2
BRANCH_OR_TAG=$3
LTS_DISTRIBS=$(curl --silent "https://mirror.xivo.solutions/version/lts")

# Common checks
check_distribution

check_version_is_valid
# Sanitize version
XS_VERSION=$(echo ${PKG_VERSION} | grep -oE '[0-9]{4}\.[0-9]{2}\.[0-9]{2}') # e.g. 2017.11.08
XS_RELEASE=$(echo ${XS_VERSION} | grep -oE '[0-9]{4}\.[0-9]{2}')            # e.g. 2017.11

check_version_and_distribution_consistency

case ${BUILD_TYPE} in
dev | unstable)
	ensure_git_tag_inexistent
	export_variables
	;;

rc)
	VERSION_FROM_TAG=$(parse_version $BRANCH_OR_TAG)
	check_changelog_against_tag
	ensure_git_tag_inexistent
	ensure_git_and_build_rc_tag_existent
	export_variables
	;;

*)
	echo "Invalid <build_type>: ${BUILD_TYPE}"
	;;
esac
