#!/bin/bash

failed_downloads=""
failed_hash=""

failed_download () {
	failed_downloads="$failed_downloads $name"
	printf "$@"
}

pkg_root="$(readlink -f $(dirname $0))"

download_file () {
	file=$(basename "$url")

	if [[ -f "$file" ]]; then
		return 0
	fi

	wget "$url" || {
		failed_download "Error while downloading %s package from %s\n" "$name" "$url"
		return 1
	}
}

download_git () {
	file=${name}-${version}.tar.xz

	if [[ -f "$file" ]]; then
		return 0
	fi

	# Clone the repo if it doesn't exist
	if [[ ! -d "$name" ]]; then
		if [[ -n "$branch" ]]; then
			git clone --single-branch --branch "$branch" "$url" "$name" || {
				failed_download "Error cloning %s --single-branch=%s\n" "$name" "$branch"
				return 1
			}
		else
			git clone "$url" "$name" || {
				failed_download "Error cloning %s\n" "$name"
				return 1
			}
		fi
	fi

	pushd "$name" > /dev/null || exit 1

	# Check if the ref already exists.  Attempt to pull if it doesn't
	git rev-parse -q --verify "$ref^{commit}" || {
		git pull || {
			failed_download "Error pulling %s\n" "$name"
			popd > /dev/null
			return 1
		}

		git rev-parse -q --verify "$ref^{commit}" || {
			failed_download "Did not find ref %s in repo %s after pulling\n" "$ref" "$url"
			popd > /dev/null
			return 1
		}
	}

	# Create the archive from the ref
	git archive --format=tar --prefix="${name}-${version}/" "$ref" | xz -z > "../${file}"

	popd > /dev/null
	return 0
}

gen_cert_bundle () {
	printf "%s" "$failed_downloads" | grep -qw "certdata"
	if [[ $? -eq 0 ]]; then
		printf "\nError: Failed to download CA certificate data\n"
		return 1
	fi

	printf "%s" "$failed_hash" | grep -qw "certdata"
	if [[ $? -eq 0 ]]; then
		printf "\nError: SHA256 verification failed for CA certificate data\n"
		return 1
	fi

	./mk-ca-bundle.pl -f -n ca-certificates.crt
	if [[ $? -ne 0 ]]; then
		printf "\nError: Failed to generate CA certificate bundle\n"
		return 1
	fi
}

pushd "${pkg_root}" > /dev/null || exit 1
current=1
total=$(sed -e '/^#/d' -e '/^$/d' packages.current | wc -l)

while IFS=, read name version type url hash branch ref
do
	printf "\033[1mpackage %02d/%d %s\033[0m\n" "$current" "$total" "$name"
	if [[ "$type" = "file" ]]; then
		download_file || continue
	elif [[ "$type" = "git" ]]; then
		download_git || continue
	else
		printf "Bad package type %s for package %s\n" "$type" "$name"
		exit 1
	fi

	printf "%s *%s" "$hash" "$file" | sha256sum -c
	if [[ $? != 0 ]]; then
		printf "Error while checking sha256sum for %s package\n" "$name"
		failed_hash="$failed_hash $name"
	fi

	(( current++ ))

done < <(sed -e '/^#/d' -e '/^$/d' packages.current)

# Generate the ca-certificates.crt bundle
gen_cert_bundle

if [[ -n "$failed_downloads" ]]; then
	printf "\nError: Failed to download these packages: %s\n" "$failed_downloads"
fi

if [[ -n "$failed_hash" ]]; then
	printf "\nError: SHA256 verification failed for these packages: %s\n" "$failed_hash"
fi

popd > /dev/null

