#!/usr/bin/env bash
# gettermbg -- Check whether the terminal has a light or dark background.
#
# Queries the Xterm background and uses the formula from:
# https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/apply-windows-themes#know-when-dark-mode-is-enabled
#
# A more advanced tool is available at:
# https://github.com/rocky/shell-term-background/blob/master/term-background.bash

usage() {
	echo "Usage: ${0##*/} {-d|-l|--is-dark|--is-light}"
}
vmsg() {
	echo "${0##*/}: $*" >&2
}

if [[ ! -t 0 ]]; then
	exit 1
fi

exec </dev/tty >/dev/tty
trap "stty echo" EXIT
stty -echo

# Request Xterm background color OSC
printf '\e]11;?\e\\' # returns '\e]11;rgb:XXXX/YYYY/ZZZZ\e\\'

# Request Primary Device Attributes, to avoid timeouts when the terminal
# doesn't understand the Xterm OSC
printf '\e[c' # returns '\e[?XXXc'

# (XXX: Could also use DSR '\e[5n' => '\e[0n')

# Read up to the ? in the middle of Primary DA answer
if read -r -d '?' -t 2 ans1 &&
   read -r -d 'c' -t 2 ans2; then
	ans="${ans1}?${ans2}c"
	re=$'\e\\]11;(rgb:([[:alnum:]]+)/([[:alnum:]]+)/([[:alnum:]]+))[\a\e]'
	if [[ $ans1 =~ $re ]]; then
		declare -i r="0x${BASH_REMATCH[2]}"
		declare -i g="0x${BASH_REMATCH[3]}"
		declare -i b="0x${BASH_REMATCH[4]}"
		# X11 colors are rrrr/gggg/bbbb, e.g. "rgb:ffff/f7f7/dfdf"
		# or "rgb:1c1c/1c1c/1c1c".
		r="r >> 8"
		g="g >> 8"
		b="b >> 8"
		# Use the formula from Microsoft
		declare -i is_light='(5*g + 2*r + b) > (8*128)'

		case $1 in
		"")		echo "${BASH_REMATCH[1]}";;
		-l|--is-light)	(( is_light ));;
		-d|--is-dark)	(( !is_light ));;
		*)		usage >&2; exit 2;;
		esac
	elif [[ $ans1 == $'\e[' ]]; then
		# No answer to color inquiry, all we got is Primary DA
		case $1 in
		"")		vmsg "no OSC reply from terminal"; exit 1;;
		-l|--is-light)	false;;
		-d|--is-dark)	true;;
		*)		usage >&2; exit 2;;
		esac
	else
		vmsg "invalid DA reply from terminal: ${ans1@Q}"
		exit 3
	fi
else
	vmsg "did not receive Primary DA reply from terminal"
	exit 4
fi
