#!/bin/sh
set -u

REPERTOIRE=${JOYEUSE_BATTERIE_REPERTOIRE:-/var/lib/joyeuse-batterie}
ETAT=$REPERTOIRE/etat
CAPACITE=${JOYEUSE_BATTERIE_CAPACITE:-/sys/class/power_supply/qcom_qg/capacity}
RESTAURATION=${JOYEUSE_BATTERIE_RESTAURATION:-/sys/class/power_supply/qcom_qg/restaure_capacite}
AGE_MAX=300

erreur()
{
	printf '%s\n' "joyeuse-batterie: $*" >&2
}

entier()
{
	case "$1" in
		''|*[!0-9]*) return 1 ;;
		*) return 0 ;;
	esac
}

restaure()
{
	[ -f "$ETAT" ] || return 0

	version=
	epoque=
	soc=
	reste=
	IFS=' ' read -r version epoque soc reste < "$ETAT" || {
		erreur "etat illisible"
		return 0
	}

	[ "$version" = 1 ] && entier "$epoque" && entier "$soc" &&
		[ "${#epoque}" -le 10 ] && [ "${#soc}" -le 3 ] &&
		[ -z "$reste" ] && [ "$soc" -le 100 ] || {
		erreur "etat invalide"
		return 0
	}

	maintenant=$(date +%s) || {
		erreur "horloge illisible"
		return 0
	}
	entier "$maintenant" || {
		erreur "horloge invalide"
		return 0
	}

	age=$((maintenant - epoque))
	[ "$age" -ge 0 ] && [ "$age" -le "$AGE_MAX" ] || return 0
	[ -w "$RESTAURATION" ] || {
		erreur "restauration indisponible"
		return 0
	}
	printf '%s\n' "$soc" > "$RESTAURATION" || {
		erreur "restauration refusée"
		return 0
	}
}

sauvegarde()
{
	[ -r "$CAPACITE" ] || {
		erreur "capacité illisible"
		return 1
	}

	soc=
	IFS= read -r soc < "$CAPACITE" || {
		erreur "capacité illisible"
		return 1
	}
	maintenant=$(date +%s) || {
		erreur "horloge illisible"
		return 1
	}
	entier "$soc" && [ "$soc" -le 100 ] && entier "$maintenant" || {
		erreur "état courant invalide"
		return 1
	}

	umask 077
	mkdir -p "$REPERTOIRE" || {
		erreur "répertoire d'état inaccessible"
		return 1
	}
	chmod 700 "$REPERTOIRE" || {
		erreur "permissions d'état impossibles"
		return 1
	}
	temporaire=$(mktemp "$REPERTOIRE/.etat.XXXXXX") || {
		erreur "état temporaire impossible"
		return 1
	}
	trap 'rm -f "$temporaire"' EXIT HUP INT TERM
	printf '1 %s %s\n' "$maintenant" "$soc" > "$temporaire" || {
		erreur "écriture d'état impossible"
		return 1
	}
	mv -f "$temporaire" "$ETAT" || {
		erreur "remplacement d'état impossible"
		return 1
	}
	trap - EXIT HUP INT TERM
}

case "${1:-}" in
	restaure) restaure ;;
	sauvegarde) sauvegarde ;;
	*) erreur "action invalide"; exit 2 ;;
esac
