#!/bin/bash

CURMAJORV=`dpkg -l|grep zentyal-core | awk '{print $3}' | cut -d'.' -f1`
CURMINORV=`dpkg -l|grep zentyal-core | awk '{print $3}' | cut -d'.' -f2`
CURV="${CURMAJORV}.${CURMINORV}"
KEYURL="keys.zentyal.org/zentyal-${CURV}-packages-com.asc"
APT_AUTH_CONF='/etc/apt/auth.conf.d/zentyal-commercial.conf'
LK_REGEX="^[A-Z0-9]{5}-[A-Z0-9]{5}.[A-Z0-9]{5}-[A-Z0-9]{5}$"

SHELL_CMD='/usr/share/zentyal/shell'

# Preparing request data
SERVER_UUID=$(cat /sys/class/dmi/id/product_uuid | sed -E "s/$/$(date +-%s)/" | tee /var/lib/zentyal/.product_uuid)
SERVER_VERSION=$($SHELL_CMD EBox::Config::version)
LK=$1

function checkGPG
{
	logger UCP[$$] INFO: Looking for gnupg package...
	dpkg -s gnupg &> /dev/null
	if [ $? -eq 0 ];
	then
		logger UCP[$$] INFO: gnupg already installed
	else
		logger UCP[$$] INFO: gnupg is NOT installed! Trying to install it...
		apt-get install gnupg -y
	fi
	# Importing key
	local KEY_NAME="$(basename ${KEYURL})"
	find /etc/apt/trusted.gpg.d/ -type f -iname "${KEY_NAME}*" -exec rm {} \;
	wget -q ${KEYURL} -P /etc/apt/trusted.gpg.d/
}

function removeCache
{
	rm -f $1
}

function getCurrentLK
{
	OLDLK=$($SHELL_CMD '$global->getLicenseData("license_key")' 2>/dev/null)
	if [[ -z "$OLDLK" ]] || ! echo "$OLDLK" | grep -qE "$LK_REGEX"; then
		OLDLK=''
	fi
}

SAVE_LICENSE_CMD='/usr/share/zentyal/save-license-data'
LICENSE_JSON_FILE='/var/lib/zentyal/tmp/.license-data.json'

function saveLicenseToRedis
{
	local LK_CODE="$1"
	local LK_TYPE="$2"
	local LK_EXPIRATION="$3"
	local LK_USERS="$4"
	local LK_STATUS_CODE="$5"
	local LK_STATUS_LABEL="$6"
	local SERVER_HASH="$7"
	local UCP_CLIENT_ID="$8"
	local UCP_CLIENT_SECRET="$9"
	local SRV_UUID="${10}"

	local JSON_DATA=$(jq -n \
		--arg lk "$LK_CODE" \
		--arg lt "$LK_TYPE" \
		--arg exp "$LK_EXPIRATION" \
		--arg usr "$LK_USERS" \
		--arg sc "$LK_STATUS_CODE" \
		--arg sl "$LK_STATUS_LABEL" \
		--arg sh "$SERVER_HASH" \
		--arg ci "$UCP_CLIENT_ID" \
		--arg cs "$UCP_CLIENT_SECRET" \
		--arg su "$SRV_UUID" \
		'{
			license_key: $lk,
			license_type: $lt,
			expiration_date: $exp,
			users: $usr,
			status_code: $sc,
			status_label: $sl,
			server_hash: $sh,
			ucp_client_id: $ci,
			ucp_client_secret: $cs,
			server_uuid: $su
		}')

	# Always write JSON to file (for the CGI caller to read)
	echo "$JSON_DATA" > $LICENSE_JSON_FILE
	chmod 0660 $LICENSE_JSON_FILE
	chown ebox:ebox $LICENSE_JSON_FILE

	# Save to Redis directly (skip if called from webadmin to avoid lock deadlock)
	if [ -z "$EBOX_SKIP_REDIS_SAVE" ]; then
		echo "$JSON_DATA" | $SAVE_LICENSE_CMD
	fi
}

function enableLicense
{
	local API_URL='https://ucp.zentyal.com/api/v2/licenses/activate'
	local URL_REPOSITORY='https://packages.zentyal.com'
	local RESPONSE_DATA_FILE_TMP=$(mktemp /tmp/XXXXXXX)

	# Preparing the data with JSON encoding
	JSON_STRING=$( jq -n \
					--arg lk "$LK" \
					--arg pc "$SERVER_UUID" \
					--arg v "ZS$SERVER_VERSION" \
					'{
						license_key: $lk,
						server_uuid: $pc,
						server_version: $v
					}'
				)

	# Run the request to "activate the license" (API v2)
	HTTP_CODE=$(/usr/bin/timeout 30 /usr/bin/curl -s -X POST -H "Content-Type: application/json" -d "$JSON_STRING" $API_URL -w "%{http_code}" -o $RESPONSE_DATA_FILE_TMP)

	if [ "$HTTP_CODE" -eq "200" ]; then
		# Parse the v2 response
		LK_DATA=$(cat $RESPONSE_DATA_FILE_TMP | jq -r ".data")

		LK_CODE=$(echo $LK_DATA | jq -r ".code")
		LK_EXPIRATION=$(echo $LK_DATA | jq -r ".expiration_date")
		LK_TYPE=$(echo $LK_DATA | jq -r ".license_type.code")
		LK_USERS=$(echo $LK_DATA | jq -r ".users")
		LK_STATUS_CODE=$(echo $LK_DATA | jq -r ".status.code")
		LK_STATUS_LABEL=$(echo $LK_DATA | jq -r ".status.label")
		SERVER_HASH=$(echo $LK_DATA | jq -r ".server_hash")

		# Get OAuth credentials
		OAUTH_DATA=$(cat $RESPONSE_DATA_FILE_TMP | jq -r ".oauth_client")
		UCP_CLIENT_ID=$(echo $OAUTH_DATA | jq -r ".id")
		UCP_CLIENT_SECRET=$(echo $OAUTH_DATA | jq -r ".secret")

		# Save all license data to Redis
		saveLicenseToRedis "$LK_CODE" "$LK_TYPE" "$LK_EXPIRATION" "$LK_USERS" \
			"$LK_STATUS_CODE" "$LK_STATUS_LABEL" "$SERVER_HASH" \
			"$UCP_CLIENT_ID" "$UCP_CLIENT_SECRET" "$SERVER_UUID"

		# Setup APT authentication for commercial packages
		echo "machine $URL_REPOSITORY login $LK_CODE password $SERVER_UUID" > $APT_AUTH_CONF
		chmod 600 $APT_AUTH_CONF

		touch /var/lib/zentyal/.commercial-edition
		logger UCP[$$] INFO: License key $LK_CODE was enabled via API v2.
		checkGPG
		removeCache $RESPONSE_DATA_FILE_TMP
	else
		# Parse v2 error response
		ERROR_CODE=$(cat $RESPONSE_DATA_FILE_TMP | jq -r ".error_code // empty")
		RES_MSG=$(cat $RESPONSE_DATA_FILE_TMP | jq -r ".message // empty")
		SUGGESTED=$(cat $RESPONSE_DATA_FILE_TMP | jq -r ".suggested_action // empty")

		logger UCP[$$] ERROR: Activation failed [HTTP $HTTP_CODE] [$ERROR_CODE]: $RES_MSG.
		if [ -n "$SUGGESTED" ]; then
			logger UCP[$$] INFO: Suggested action: $SUGGESTED
		fi

		# Write error info to stdout for the caller (Perl model) to capture
		echo "$ERROR_CODE"

		removeCache $RESPONSE_DATA_FILE_TMP
		exit 1
	fi
}

function notifyLicenseChange
{
	local RESPONSE_DATA_FILE_TMP=$(mktemp /tmp/XXXXXXX)
	local API_URL='https://ucp.zentyal.com/api/lk/upgrade'

	# Preparing the data with JSON encoding
	JSON_STRING=$(jq -n \
					--arg oldlk "$OLDLK" \
					--arg newlk "$LK" \
					'{
						origin_license_code: ($oldlk // null),
						destination_license_code: $newlk,
					}'
				)

	# Run the request to "upgrade the license"
	REQUEST=$(/usr/bin/curl -s -X POST -H "Content-Type: application/json" -d "${JSON_STRING}" ${API_URL} -w "%{http_code}" -o ${RESPONSE_DATA_FILE_TMP})

	if [ $REQUEST -eq "201" ]; then
		logger UCP[$$] INFO: License key upgrade request sent successfully.
		removeCache ${RESPONSE_DATA_FILE_TMP}
	else
		LK_ERR=$(cat ${RESPONSE_DATA_FILE_TMP} | jq -r ".message // empty")
		logger UCP[$$] ERROR: License upgrade notification failed: ${LK_ERR}
		removeCache ${RESPONSE_DATA_FILE_TMP}
		# Do not exit with error; activation was successful
	fi
}

# License key checks
if [ -z $LK ]
then
	echo "Usage: $0 XXXXX-XXXXX-XXXXX-XXXXX"
	exit 126
fi

if ! echo "$LK" | grep -qE "$LK_REGEX"
then
	echo "Invalid key format."
	echo "Make sure your license matchs the following format: XXXXX-XXXXX-XXXXX-XXXXX"
	exit 1
fi

# Calling the functions
getCurrentLK
enableLicense
notifyLicenseChange
exit 0
