#!/usr/bin/env bash
# charge -- control ThinkPad laptop charge threshold

. lib.bash || exit

sysfs_ctl() {
	local acpidev=$1 start=$2 stop=$3
	sudo ctl \
		/sys/class/power_supply/$acpidev/charge_start_threshold=$start \
		/sys/class/power_supply/$acpidev/charge_stop_threshold=$stop
}

upower_get() {
	local acpidev=$1
	busctl get-property \
		org.freedesktop.UPower \
		/org/freedesktop/UPower/devices/battery_$acpidev \
		org.freedesktop.UPower.Device ChargeThresholdEnabled
}

upower_ctl() {
	local acpidev=$1 bool=$2
	busctl call \
		org.freedesktop.UPower \
		/org/freedesktop/UPower/devices/battery_$acpidev \
		org.freedesktop.UPower.Device EnableChargeThreshold \
		b $bool
}

acpidev=BAT0
dev=/sys/class/power_supply/$acpidev

if [[ ! -e $dev ]]; then
	vdie "no battery on this system: $acpidev"
elif [[ ! -e $dev/charge_stop_threshold ]]; then
	vdie "battery $acpidev does not support charge thresholds"
fi

statefile=/var/lib/upower/charging-threshold-status

if [[ -e $statefile ]]; then
	upower=1
fi

case $1 in
	on|save|limit|80)
		if (( upower )); then
			vmsg "setting threshold via upower"
			upower_ctl $acpidev true
		else
			vmsg "setting threshold via sysfs"
			sysfs_ctl $acpidev 75 80
		fi;;
	off|normal|full|100)
		if (( upower )); then
			vmsg "setting threshold via upower"
			upower_ctl $acpidev false
		else
			vmsg "setting threshold via sysfs"
			sysfs_ctl $acpidev 0 100
		fi;;
	?*)
		vdie "unrecognized argument: $1";;
esac

echo "Current values:"
echo "  Status: $(<$dev/status), $(<$dev/capacity)%"
echo "  Stop charging at: $(<$dev/charge_stop_threshold)%"
echo "  Start charging at: $(<$dev/charge_start_threshold)%"

if (( upower )); then
	value=$(< "$statefile")
	case $value in
		0) mode="Maximize Charge";;
		1) mode="Preserve Battery Health";;
		*) mode="Unknown mode ${value@Q}";;
	esac
	echo "  Current UPower mode: $mode"
else
	echo "  Not managed by UPower."
fi
