#!/bin/bash
#
# This will update the USN website
#
# Copyright 2018-2020, Canonical, Ltd.
# Author: Tyler Hicks <tyhicks@canonical.com>
# License: GPLv3
set -e
export LANG=C

. "$HOME"/.ubuntu-cve-tracker.conf
database="$usn_db_copy"
action=
usn_tool_repo="lp:usn-tool"
FILES_TO_CLEANUP=()

# $0: program name
usage() {
	echo "Usage: $0 <ACTION> [OPTION] <USN>..."
	echo "Update the USN website git tree with markdown for the specified <USN>."
	echo "Specify <USN> with only the number portion of the ID, such as 2165-1."
	echo ""
	echo "Valid actions:"
	echo "  -a              Add <USN> to the USN site"
	echo "  -r              Remove <USN> from the USN site"
	echo "  -u              Update <USN> information the USN site"
	echo ""
	echo "Valid options:"
	echo "  -d [DATABASE]   Use DATABASE as the USN db to consult for information on <USN>"
	echo "  -h              Print usage information"
}

perr() {
	echo "ERROR: $1" 1>&2
}

# $1: USN database
# $2: The USN number
is_usn_in_db() {
	if ! "$usn_tool"/usn.py --db "$1" --show "$2" >/dev/null 2>&1; then
		return 1
	fi

	return 0
}

# $1: git tree path
is_usn_tool_tree_updated() {
	local TREE_REV="$(cd "$1" && git log --format=%H -1)"
	local REMOTE_REV="$(git ls-remote  $(cd $1 && git remote get-url origin) HEAD | awk '{ print $1; }')"
	if ! [ "${TREE_REV}" == "${REMOTE_REV}" ] ; then
		return 1
	fi

	return 0
}

# push to the API provided by the web team for https://ubuntu.com/security/notices
# $1: The action string (add, update, or remove)
# $2: USN database
# $3: The USN number
push_to_website_api() {
	local action="$1"
	local database="$2"
	local usn="$3"
	#TMP_YAML=$(mktemp -u)
	#TMP_PICKLE=$(mktemp -u)
	TMP_JSON=$(mktemp -u)

	FILES_TO_CLEANUP+=($TMP_JSON)

	# export the single USN from the pickle to a yaml file
	if ! "$usn_tool"/usn.py --db "$database" --export-json "$usn" >"$TMP_JSON" ; then
		perr "Failed to export $usn from pickle to yaml"
		exit 1
	fi

	# post the single USN json file to the website API
	if ! "$UCT"/scripts/publish-usn-to-website-api.py --action "$action" --json "$TMP_JSON" --prefix "USN-" --stop --no-upsert; then
		perr "Failed to publish $usn pickle to website API"
		exit 1
	fi

}


cleanup() {
	for file in "${FILES_TO_CLEANUP[@]}"; do
		if test -f "$file"; then
			rm $file
		fi
	done
}

while getopts "ad:hru" opt ; do
	case "$opt" in
		a) action=add;;
		d) database="$(realpath "$OPTARG")";;
		h) usage; exit 0;;
		r) action=remove;;
		u) action=update;;
		?) usage 1>&2; exit 1;;
	esac
done
shift $((OPTIND - 1))

if [ -z "$action" ]; then
	usage 1>&2
	exit 1
fi

if [ $# -lt 1 ]; then
	usage 1>&2
	exit 1
fi
usns="$@"

trap cleanup EXIT
if ! (cd "$usn_tool" && test -d .git) ; then
	perr "The directory ($usn_tool) is not a git tree"
	perr "Please clone from ${usn_tool_repo} and update $HOME/.ubuntu-cve-tracker.conf"
	exit 1
fi
if ! is_usn_tool_tree_updated "$usn_tool"; then
	perr "The usn-tool git tree ($usn_tool) is out of sync"
	exit 1
fi

if ! python3 -c "import macaroonbakery" >/dev/null 2>&1 ; then
	perr "Missing dependency for publishing to USN API"
	perr "Please make sure you have python3 and pip install macaroonbakery"
	exit 1
fi


for usn in $usns; do
	if ! is_usn_in_db "$database" "$usn"; then
		perr "Ensure that USN-$usn is in $database and try again"
		exit 1
	fi

	push_to_website_api "$action" "$database" "$usn"
done

echo "Success! Please verify the USN page(s):"
echo
for usn in $usns; do
	echo "  https://ubuntu.com/security/notices/USN-$usn"
done
