#!/bin/bash -e

ui__setenv()
{
	local var
	for var in ${1}; do
		local code="export ${var}='${2}'"
		eval "${code}"
	done
}

ui_auto_buildflags()
{
	local -A presets=(
		[debian]=""
		[light]="-Wall -pedantic"
		[normal]="-Wall -Wextra -pedantic -Wno-unused-parameter"
		[hard]="-Wall -Wextra -Wconversion -Wsign-conversion -pedantic"
		[permissive]="-fpermissive -Wno-all"
	)
	local flags=$(dpkg-buildflags --list | tr "\n" " ")
	local appendableFlags=$(dpkg-buildflags --list | grep --invert-match --regexp=CPPFLAGS --regexp=LDFLAGS)
	local spaceSeparatedArgs="--help --completion --unset --noerror --noopt ${!presets[*]}" errorFlag="-Werror" debBuildOptions=""

	ui_auto_buildflags:log() { printf "%s\n" "${1}" >&2; }
	ui_auto_buildflags:help()
	{
		ui_auto_buildflags:log "Usage: ui-auto-buildflags ${spaceSeparatedArgs// / | } [<extra-flags>...]"
		ui_auto_buildflags:log "Conveniently get 'recommended' buildflags for development or code testing."
		ui_auto_buildflags:log "Presets: light (-Wall -pedantic), normal (DEFAULT: all+extra warnings except 'unused-parameter'), hard (all warnings)."
	}
	ui_auto_buildflags:dump()  # <preset> [<extra-flags>...]
	{
		[[ -v presets[${1}] ]] || { ui_auto_buildflags:log "E: Unknown preset: ${1}"; return 1; }

		local flag
		for flag in ${appendableFlags}; do
			ui__setenv "DEB_${flag}_APPEND" "${presets[${1}]} ${errorFlag} ${*:2}"
		done
		# FORTIFY_SOURCE changes code and might hide warnings, so we strip it.
		DEB_BUILD_OPTIONS="${debBuildOptions}" DEB_CPPFLAGS_STRIP="-D_FORTIFY_SOURCE=2" dpkg-buildflags --export=sh
	}

	local -i p=1
	while [ "${!p:0:2}" == "--" ]; do
		case ${!p} in
			--help) ui_auto_buildflags:help; return 0;;
			--completion) printf "complete -W '%s' ui-auto-buildflags" "${spaceSeparatedArgs}"; return 0;;
			--unset) printf "unset %s\n" "${flags}"; return 0;;
			--noerror) errorFlag="-Wno-error";;
			--noopt) debBuildOptions="noopt";;
			*) ui_auto_buildflags:log "E: Unknown option: ${!p}"; ui_auto_buildflags:help; return 1;;
		esac
		p+=1
	done
	ui_auto_buildflags:dump "${!p-normal}" "${@:$((++p))}"
}

ui_auto_buildflags "${@}"
