set -e;

# maintain a cached copy of coreos pxe image

if [ -z "${IMG_URL}" -o -z "${ITMP}" -o -z "${V}" ]; then
	exit 1
fi

if [ ${V} -eq 3 ]; then
	set -x
fi

# coreos gpg signing key
# $ gpg2 --list-keys --list-options show-unusable-subkeys \
#     --keyid-format SHORT 04127D0BFABEC8871FFB2CCE50E0885593D2DCB4
# pub   rsa4096/93D2DCB4 2013-09-06 [SC]
#       04127D0BFABEC8871FFB2CCE50E0885593D2DCB4
# uid         [ unknown] CoreOS Buildbot (Offical Builds) <buildbot@coreos.com>
# sub   rsa4096/74E7E361 2013-09-06 [S] [expired: 2014-09-06]
# sub   rsa4096/E5676EFC 2014-09-08 [S] [expired: 2015-09-08]
# sub   rsa4096/1CB5FA26 2015-08-31 [S] [expired: 2017-08-30]
# sub   rsa4096/B58844F1 2015-11-20 [S] [revoked: 2016-05-16]
# sub   rsa4096/2E16137F 2016-05-16 [S] [expired: 2017-05-16]
# sub   rsa4096/EF4B4ED9 2017-05-22 [S] [expires: 2018-06-01]
# sub   rsa4096/0638EB2F 2018-02-10 [S] [expires: 2019-06-01]
GPG_LONG_ID="50E0885593D2DCB4"
GPG_KEY="-----BEGIN PGP PUBLIC KEY BLOCK-----

[encoded data, 17745 characters]
2jibQQI=
=KhYl
-----END PGP PUBLIC KEY BLOCK-----
"

# prints passed flags if verbosity level is lower; to be used inside
# output capture (backticks or $())
function be_quiet() {
	local verbosity	#verbosity level
	local flags	#silencing flags to use

	verbosity=$1
	flags=$2

	if [ $verbosity -lt 3 ]; then
		printf '%s\n' "${flags}"
	fi
}

# gpg verify a file using the provided key
function gpg_verify() {
	local file	#file to verify
	local sigfile	#signature file (assumed to be suffixed form of file to verify)
	local key	#signing key
	local keyid	#signing key signature
	local verbosity	#verbosity level

	local quiet
	local gpghome

	file=$1
	sigfile=$2
	key=$3
	keyid=$4
	verbosity=$5

	quiet=$(be_quiet $verbosity '--quiet --no-verbose')
	gpghome=$(mktemp -d)
	trap "{ rm -rf '${gpghome}'; }" RETURN EXIT
	if ! gpg --homedir="${gpghome}" --batch --quiet --import <<<"${key}"; then
		return 1
	fi
	if ! gpg --homedir="${gpghome}" --batch ${quiet} --trusted-key "${keyid}" --verify "${sigfile}" "${file}"; then
		return 1
	fi
	return 0
}

function do_wget() {
	local out	#output file
	local url	#url of a file to be downloaded
	local verbosity	#verbosity level

	local quiet
	local short_out

	out=$1
	url=$2
	verbosity=$3

	quiet=$(be_quiet $verbosity '--quiet')
	if [ "${quiet}" ]; then
		# strip the working directory from output path, so we get
		# something like build-rkt/tmp/coreos-common/pxe.img
		# instead of /home/foo/projects/rkt/rkt/build-rkt/...
		short_out="${out#${PWD}/}"
		printf '  %-12s %s\n' 'WGET' "${url} => ${short_out}"
	fi
	wget ${quiet} --tries=20 --output-document="${out}" "${url}" # the wget default for retries is 20 times.
}

function cat_to_stderr_if_verbose() {
	local file
	local verbosity

	file=$1
	verbosity=$2

	if [ -z $(be_quiet $verbosity 'empty-if-verbose') ]; then
		cat "${file}" >&2
	fi
}

# maintain an gpg-verified url cache, assumes signature available @ $url.sig
function cache_url() {
	local cache	#verified cache, will be downloaded from the url if bad or missing
	local url	#url of the file to be downloaded
	local key	#key used for verification
	local keyid	#id of a key used for verification
	local verbosity	#verbosity level

	local urlhash
	local sigfile
	local sigurl
	local gpgout

	cache=$1
	url=$2
	key=$3
	keyid=$4
	verbosity=$5

	urlhash=$(echo -n "${url}" | md5sum)
	sigfile="${cache}.${urlhash%% *}.sig"
	sigurl="${url}.sig"

	gpgout=$(mktemp)
	trap "{ rm -f '${gpgout}'; }" RETURN EXIT
	# verify the cached copy if it exists
	if ! gpg_verify "${cache}" "${sigfile}" "${key}" "${keyid}" "${verbosity}" 2>"${gpgout}"; then
		# refresh the cache on failure, and verify it again
		cat_to_stderr_if_verbose "${gpgout}" "${verbosity}"
		do_wget "${cache}" "${url}" "${verbosity}"
		do_wget "${sigfile}" "${sigurl}" "${verbosity}"
		if ! gpg_verify "${cache}" "${sigfile}" "${key}" "${keyid}" "${verbosity}" 2>"${gpgout}"; then
			# print an error if verification failed
			cat "${gpgout}" >&2
			return 1
		fi
		cat_to_stderr_if_verbose "${gpgout}" "${verbosity}"
	else
		cat_to_stderr_if_verbose "${gpgout}" "${verbosity}"
	fi

	# file $cache exists and can be trusted
	touch "${cache}"
}

# cache pxe image
cache_url "${ITMP}/pxe.img" "${IMG_URL}" "${GPG_KEY}" "${GPG_LONG_ID}" "${V}"
