#!/bin/sh -eu

CPU=
GOVERNOR_AC_ON=
GOVERNOR_AC_OFF=
DEFAULT_GOVERNOR_AC_ON=ondemand
DEFAULT_GOVERNOR_AC_OFF=ondemand
# Dirk Brandewie stated that in case of intel_pstate driver
# "powersave roughly equal to ondemand".
# See https://bugzilla.kernel.org/show_bug.cgi?id=73421#c1
# for details.
DEFAULT_INTEL_PSTATE_GOVERNOR_AC_ON=powersave
DEFAULT_INTEL_PSTATE_GOVERNOR_AC_OFF=powersave

. shell-error

[ -f /etc/sysconfig/cpufreq-simple ] && . /etc/sysconfig/cpufreq-simple

PATH='/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin'
CPUFREQ=/sys/devices/system/cpu/cpu0/cpufreq
GOVERNORS="$CPUFREQ/scaling_available_governors"
SCALING_DRIVER="$CPUFREQ/scaling_driver"
cmd="${1-}"

get_ac_state()
{
	local state_file
	if [ -d /proc/acpi/ac_adapter/ ]; then
		state_file="$(find /proc/acpi/ac_adapter/ -name state | head -1)"
		if [ -n "$state_file" -a -r "$state_file" ]; then
			sed 's;^state:[[:blank:]]*;;' "$state_file" | head -1
			return 0
		fi
	fi
	# Treat unknown AC state as on-line
	echo "on-line"
}

get_scaling_driver()
{
	if [ -f "$SCALING_DRIVER" ]; then
		cat "$SCALING_DRIVER"
	fi
}

init_command()
{
	local ac_state="$(get_ac_state)"
	[ -n "$ac_state" ] && echo "ac-$ac_state"
}

set_cpufreq()
{
	local cpu_list=

	# getopt seems overkill right now
	if [ "$1" = "-g" -a -n "$2" ]; then
		grep -Fq -- "$2" "$GOVERNORS" || modprobe "cpufreq_$2"
	fi
	for i in $CPU; do
		cpu_list="$cpu_list${cpu_list:+,}$i"
	done

	[ -n "$cpu_list" ] || cpu_list="all"

	cpupower --cpu "$cpu_list" frequency-set "$@"
}

if ! [ -f "$CPUFREQ/scaling_governor" -a -f "$GOVERNORS" ]; then
	fatal "system not configured correctly for CPU frequency scaling"
fi

[ -n "$cmd" ] || cmd="$(init_command)"

if [ -z "$cmd" ]; then
	fatal "couldn't apply initial settings"
fi

case "$cmd" in
	ac-on-line)
		if [ -z "$GOVERNOR_AC_ON" ]; then
			[ "$(get_scaling_driver)" = intel_pstate ] &&
				GOVERNOR_AC_ON="$DEFAULT_INTEL_PSTATE_GOVERNOR_AC_ON" ||
				GOVERNOR_AC_ON="$DEFAULT_GOVERNOR_AC_ON"
		fi
		set_cpufreq -g "$GOVERNOR_AC_ON"
		;;
	ac-off-line)
		if [ -z "$GOVERNOR_AC_OFF" ]; then
			[ "$(get_scaling_driver)" = intel_pstate ] &&
				GOVERNOR_AC_OFF="$DEFAULT_INTEL_PSTATE_GOVERNOR_AC_OFF" ||
				GOVERNOR_AC_OFF="$DEFAULT_GOVERNOR_AC_OFF"
		fi
		set_cpufreq -g "$GOVERNOR_AC_OFF"
		;;
	*)
		fatal "unknown command: '$cmd'"
		;;
esac
