#!/usr/bin/env bash

g_analyse_all=f
g_cppcheck=t
g_clangformat=t
g_shellcheck=t
g_resume_mode=f

logfile=.tmp-check-script

die () {
	printf '\033[31mfatal:\033[m %b\n' "$@" >&2
	exit 1
}

warn () {
	printf '\033[31mwarn:\033[m %b\n' "$@" >&2
}

say () {
	printf '\033[32m%s\033[m' "$@"
}

isinstalled () {
	type "$1" >/dev/null 2>&1
}

usage () {
	printf "%s\n" \
"Usage: check [<options>] [<file>...]
Options:
-a, --all      run check on all .c .h and .sh files in src/
-h, --help     show help
-i, --in-situ  pass -i to clang-format
--resume       same as --all, but carry on with last aborted"
	exit 0
}

analyse () {
	[[ -e $1 ]] || die "file ($1) does not exist"
	say "     CHECK $1"
	if [[ $(file $1) == *shell\ script* ]]; then
		say " [checkbashisms]"
		perl ./scripts/checkbashisms.pl --force "$1"
		[[ $g_shellcheck = f ]] && return
		say " [shellcheck]"
		shellcheck "$1"
	fi
	if [[ $(file $1) == *C\ source* ]]; then
		if [[ $g_cppcheck = t ]]; then
			say " [cppcheck]"
			./scripts/cppcheck-wrapper.sh "$1"
		fi
		say " [checkpatch.pl]"
		if [[ $g_clangformat = t ]]; then
			say " [clang-format]"
			./scripts/clang-format-wrapper.sh "$1"
		fi
		./scripts/checkpatch-wrapper.sh "$1"
	fi
	printf "\n"
}

analyse_all () {
	[[ $g_resume_mode = f ]] && rm -f "${logfile}"
	for f in src/*.sh src/*.c src/*.h; do
		grep "${f}" "${logfile}" >/dev/null 2>&1 && continue
		analyse "$f"
		printf '%b\n' "${f}" >> "${logfile}"
	done
}

main () {
	[[ -e src/jgmenu.c ]] || die "must be run from top-level directory"
	[[ $# = 0 ]] && usage
	isinstalled cppcheck || { warn "cppcheck not installed"; g_cppcheck=f; }
	isinstalled clang-format || { warn "clang-format not installed"; g_clangformat=f; }
	isinstalled shellcheck || { warn "shellcheck not installed"; g_shellcheck=f; }

	for arg
	do
		opt=${arg%%=*}
		var=${arg#*=}
		case "$opt" in
		-a|-all)
			g_analyse_all=t ;;
		-i)
			g_insitu=t ;;
		-h|--help)
			usage ;;
		--resume)
			g_analyse_all=t
			g_resume_mode=t
			;;
		*)
			analyse "$var"
		esac
	done

	[[ $g_analyse_all = t ]] && analyse_all
}

main "$@"
