#!/usr/bin/env bash

#  script flash: utilise flashrom pour flasher une image ROM de Libreboot.
#
#	Copyright (C) 2014, 2015 Leah Rowe <info@minifree.org>

#    Ce programme est un logiciel libre: vous pouvez le redistribuer et/ou
#    le modifier sous les termes de la License Publique GNU Générale publiée
#    comme telle par la Free Software Foundation, soit la version 3 de la License,
#    ou (selon votre choix) n'importe quelle version plus récente.
#
#    Ce programme est fournit dans l'espoir qu'il sera utile, mais SANS AUCUNE
#    GARANTIE; sans même la garantie implicite de MARCHANBILITÉ ou de RÉPONSE 
#    À UN BUT PARTICULIER. Voyez la License Publique GNU générale pour plus
#    de détails.
#
#    Vous devriez avoir reçu une copie de la License Publique GNU générale
#    avec ce programme. Si ce n'est pas le cas, visitez 
#    <http://www.gnu.org/licenses/>.
#

# So that I one day find it again
# http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

## Don't add here. errors are expected.
[ "x${DEBUG+set}" = 'xset' ] && set -v
# set -u -e

if [ ${EUID} -ne 0 ]; then
   printf "Ce script doit être lancé en tant que root\n"
   exit 1
fi

arch="unknown"
if [ "$(uname -i)" = "i686" ] || [ "$(uname -m)" = "i686" ]; then
	arch="i686"
elif [ "$(uname -i)" = "x86_64" ] || [ "$(uname -m)" = "x86_64" ]; then
	arch="x86_64"
else
	printf "Ce script doit être exécuté sur un hôte i686 ou x86_64. x86_64 est recommandé.\n"
	exit 1
fi

usage="usage: ./flash mode path/to/yourrom.rom"
availablemodes="update, forceupdate, i945lenovo_firstflash, i945lenovo_secondflash, i945apple_firstflash"

mode="unknown"
rompath="unknown"

# User specified no or too few/many parameters
if [ $# -lt 2 ]; then
	printf "%s\n" "${usage}"
	printf "Vous avez besoin de spécifier exactement un mode et un fichier.\n"
	printf "%s\n" "${availablemodes}"
	exit 1
fi

mode="${1}"
rompath="${2}"

# User specified an invalid mode of operation
if [ "${mode}" != "update" ] && [ "${mode}" != "forceupdate" ] && [ "${mode}" != "i945lenovo_firstflash" ] && [ "${mode}" != "i945lenovo_secondflash" ] && [ "${mode}" != "i945apple_firstflash" ]; then
	printf "%s\n" "${usage}"
	printf "Mode invalide. Modes disponibles: %s\n" "${availablemodes}"
	exit 1
else
	printf "Mode sélectionné: %s\n" "${mode}"
fi

# The specified file does not exist
if [ ! -f "${rompath}" ]; then
	printf "Fichier non trouvé!\n"
	exit 1
fi

flashrom="unknown"
if [ -f "build" ]; then
	# git or libreboot_src
	flashrom="./flashrom/flashrom"
else
	# libreboot_util
	flashrom="./flashrom/${arch}/flashrom"
fi
if [ ! -f "${flashrom}" ]; then
	printf "L'exécutable flashrom n'est pas présent.\n"
	exit 1
fi

# i945 lenovobios
bucts="unknown"
flashrom_lenovobios_sst="unknown"
flashrom_lenovobios_macronix="unknown"
if [ "${mode}" = "i945lenovo_firstflash" ] || [ "${mode}" = "i945lenovo_secondflash" ]; then
	if [ -f "build" ]; then
		# git or libreboot_src
		bucts="./bucts/bucts"
		flashrom_lenovobios_sst="./flashrom/flashrom_lenovobios_sst"
		flashrom_lenovobios_macronix="./flashrom/flashrom_lenovobios_macronix"
	else
		# libreboot_util
		bucts="./bucts/${arch}/bucts"
		flashrom_lenovobios_sst="./flashrom/${arch}/flashrom_lenovobios_sst"
		flashrom_lenovobios_macronix="./flashrom/${arch}/flashrom_lenovobios_macronix"
	fi
	
	# anti-bricking precaution
	if [ ! -f "${bucts}" ]; then
		 printf "L'exécutable bucts n'est pas présent. ABANDON pour protéger le système du bousillage (bricking).\n"
		exit 1
	fi
	
	# fail if flashrom is not present
	if [ ! -f "${flashrom_lenovobios_sst}" ] || [ ! -f "${flashrom_lenovobios_macronix}" ]; then
		printf "Les exécutables flashrom ne sont pas présentes.\n"
		exit 1
	fi
fi

if [ "${mode}" = "update" ]; then
	${flashrom} -p internal -w "${rompath}"
elif [ "${mode}" = "forceupdate" ]; then
	${flashrom} -p internal:boardmismatch=force,laptop=force_I_want_a_brick -w "${rompath}"
elif [ "${mode}" = "i945apple_firstflash" ]; then
	${flashrom} -p internal:laptop=force_I_want_a_brick -w "${rompath}"
elif [ "${mode}" = "i945lenovo_firstflash" ]; then
	${bucts} 1 # needed to prevent bricks.
	# One will fail (this is harmless), and the other will succeed.
	${flashrom_lenovobios_sst} -p internal -w "${rompath}"
	${flashrom_lenovobios_macronix} -p internal -w "${rompath}"
elif [ "${mode}" = "i945lenovo_secondflash" ]; then
	${flashrom} -p internal:laptop=force_I_want_a_brick -w "${rompath}"
	${bucts} 0
fi