#!/usr/bin/env bash

#  helper script: Downloads GRUB and patches it.
#
#	Copyright (C) 2014, 2015, 2016, 2020, 2021 Leah Rowe <info@minifree.org>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

[ "x${DEBUG+set}" = 'xset' ] && set -v
set -u -e

topdir="$(realpath "$(dirname "$(dirname "$(dirname "$(dirname "$0")")")")")"

grub_revision="56ccc5ed569869fd735074ccebeaa7aab058342d"
gnulib_revision="9f48fb992a3d7e96610c4ce8be969cff2d61a01b"

usage()
{
	progname="./download grub"
	printf "Usage:\n"
	printf "\t%s            # %s\n" \
	       "${progname}" \
	       "Download GRUB"
	printf "\t%s --is-done  # %s\n" \
	       "${progname}" \
	       "Returns 0 if downloaded, 1 otherwise"
	printf "\t%s --help     # %s\n" \
	       "${progname}" \
	       "Prints this help"
}

is_done()
{
	# We need to check if any of the patches were modified. If
	# they are we need to apply their newer versions.
	if [ ! -d grub/patches ] ; then
		exit 1
	fi
	for grubpatch in ../resources/grub/patches/*; do
		cmp "${grubpatch}" patches/"${grubpatch}"
	done

	# Also check if we have the right git revision for GRUB
	current_commit=$("${topdir}"/resources/git/git \
				    -C grub show HEAD \
				    --no-patch --pretty="%H")
	if [ "${current_commit}" != "${grub_revision}" ] ; then
	    exit 1
	fi

	# Also check if we have the right git revision for gnulib
	if [ ! -d grub/gnulib ] ; then
		exit 1
	fi
	current_commit="$("${topdir}"/resources/git/git \
			    -C grub/gnulib show HEAD \
			    --no-patch --pretty="%H")"
	if [ "${current_commit}" != "${gnulib_revision}" ] ; then
	    exit 1
	fi

	exit 0
}

download()
{
	# We need to handle the case where GRUB download is
	# interrupted in the middle, so we do everything in a
	# temporary directory, and move it to the final location at
	# the end.
	tmpdir="grub.tmp"
	destdir="grub"

	# Remove the old version(s) that may still exist
	# ----------------------------------------------------------------------

	printf "Downloading GRUB\n"

	rm -Rf "${tmpdir}"
	rm -Rf "${destdir}"

	# Get latest GRUB
	# ----------------------------------------------------------------------

	# download it using git
	"${topdir}"/resources/git/git \
		clone git://git.savannah.gnu.org/grub.git "${tmpdir}" || \
	"${topdir}"/resources/git/git \
		clone http://git.savannah.gnu.org/r/grub.git "${tmpdir}"

	if [ ! -d "${tmpdir}" ]; then
		printf "grub not downloaded; check network connection?\n\n"
		exit 1
	fi

	(
	# modifications are required
	cd "${tmpdir}"
	# reset to known revision
	"${topdir}"/resources/git/git reset --hard "${grub_revision}"

	# See the is_done function for why we copy the patches in the
	# source tree.
	mkdir patches
	for grubpatch in ../resources/grub/patches/*; do
		cp "${grubpatch}" patches/
		"${topdir}"/resources/git/git am "${grubpatch}"
	done

	"${topdir}"/resources/git/git clone git://git.sv.gnu.org/gnulib gnulib
	cd gnulib/

	# NOTE: when updating this, make sure it's the version specified
	# in bootstrap.conf on that version of GRUB, as specified above
	"${topdir}"/resources/git/git reset --hard "${gnulib_revision}"
	rm -Rf .git*
	)

	printf "\n\n"

	mv "${tmpdir}" "${destdir}"
}

if [ $# -eq 0 ] ; then
	download
elif [ $# -eq 1 ] && [ "$1" = "--help" ] ; then
	usage
	exit 0
elif [ $# -eq 1 ] && [ "$1" = "--is-done" ] ; then
	is_done
fi
