#!/bin/sh
# shellcheck disable=2059
set -eu

usage() {
	cat <<-'EOF'
		Usage:
		  color -c COLOR TEXT
		  color -h
	EOF
}

help() {
	cat <<-'EOF'

		Options:
		  -c COLOR
		  -h, --help    show this message


		Print the given text with a color.

		The available colors are:
	EOF
	list_colors | sed 's/^/    /'

	cat <<-'EOF'

		Examples:

		  Print "banana" in yellow:

		    $ color -c yellow 'banana'
		    banana

		  Print "grass" in green, with a newline:

		    $ color -c green 'grass\n'
		    grass
	EOF
}


END="\033[0m"

black() {
	BLACK="\033[0;30m"
	printf "${BLACK}${1}${END}"
}

blackb() {
	BLACK_B="\033[1;30m"
	printf "${BLACK_B}${1}${END}"
}

blacki() {
	BLACK_I="\033[0;90m"
	printf "${BLACK_I}${1}${END}"
}

white() {
	WHITE="\033[0;37m"
	printf "${WHITE}${1}${END}"
}

whiteb() {
	WHITE_B="\033[1;37m"
	printf "${WHITE_B}${1}${END}"
}

red() {
	RED="\033[0;31m"
	printf "${RED}${1}${END}"
}

redb() {
	RED_B="\033[1;31m"
	printf "${RED_B}${1}${END}"
}

green() {
	GREEN="\033[0;32m"
	printf "${GREEN}${1}${END}"
}

greenb() {
	GREEN_B="\033[1;32m"
	printf "${GREEN_B}${1}${END}"
}

yellow() {
	YELLOW="\033[0;33m"
	printf "${YELLOW}${1}${END}"
}

yellowb() {
	YELLOW_B="\033[1;33m"
	printf "${YELLOW_B}${1}${END}"
}

blue() {
	BLUE="\033[0;34m"
	printf "${BLUE}${1}${END}"
}

blueb() {
	BLUE_B="\033[1;34m"
	printf "${BLUE_B}${1}${END}"
}

bluei() {
	BLUE_I="\033[0;94m"
	printf "${BLUE_I}${1}${END}"
}

purple() {
	PURPLE="\033[0;35m"
	printf "${PURPLE}${1}${END}"
}


purpleb() {
	PURPLE_B="\033[1;35m"
	printf "${PURPLE_B}${1}${END}"
}

lightblue() {
	LIGHT_BLUE="\033[0;36m"
	printf "${LIGHT_BLUE}${1}${END}"
}

lightblueb() {
	LIGHT_BLUE_B="\033[1;36m"
	printf "${LIGHT_BLUE_B}${1}${END}"
}

COLOR_LIST='
black
blackb
white
whiteb
red
redb
green
greenb
yellow
yellowb
blue
blueb
purple
purpleb
lightblue
lightblueb
blacki
bluei
'
list_colors() {
	for c in $COLOR_LIST; do
		printf '%s\n' "$("$c" "$c")"
	done
}


for flag in "$@"; do
	case "$flag" in
		--)
			break
			;;
		--help)
			usage
			help
			exit
			;;
		*)
			;;
	esac
done

COLOR_FN=''
while getopts 'c:h' flag; do
	case "$flag" in
		c)
			EXISTS=false
			for c in $COLOR_LIST; do
				if [ "$OPTARG" = "$c" ]; then
					EXISTS=true
					break
				fi
			done
			if [ "$EXISTS" = false ]; then
				printf 'Invalid color: %s\n' "$OPTARG" >&2
				exit 2
			fi
			COLOR_FN="$OPTARG"
			;;
		h)
			usage
			help
			exit
			;;
		*)
			usage >&2
			exit 2
			;;
	esac
done
shift $((OPTIND - 1))

TEXT="${1:-}"

eval "$(assert-arg -- "$COLOR_FN" '-c COLOR')"
eval "$(assert-arg -- "$TEXT"     'TEXT')"


"$COLOR_FN" "$TEXT"