#!/bin/bash
#
# shared.sh - multiple utils
#
# Copyright 2019 Luigi Santivetti <luigi.santivetti@gmail.com>

# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

function __call_module
{
	local -r this_module="$1"

	[ -n "$this_module" ] || { lets -l -e "module not defined"; return $s_err; }

	if is_opt "upins" "upall"; then
		[ ! -d "$instance_d" ] && {
			lets -l -e "trying to update an invalid instance"
			return $s_err
		}
	fi

	if is_opt "check" "watch" "upins" "upall" "doins" "doall"; then
		local __envtable; local -i ret

		__envtable="$(get_module_dependencies "envtable" $this_module)"; ret=$?
		case "$ret" in
			$s_ok )
				[ -n "$__envtable" ] && {

					# Export what's inside __envtable and check the actual table is
					# imported as a variable.
					eval "$__envtable" && declare -p -- "envtable" >/dev/null || {
							lets -l -e "failed to export enviroment table"
							return $s_err
						}

					# envtable is successfully on the stack, throw away its
					# textual representation.
					unset __envtable
				} || {
					lets -l -e "failed to get environment table"
					return $s_err
				} ;;
			* ) return $s_err ;;
		esac
	fi

	if is_opt "check"; then
		(
			# Export external variables found
			set -eu; eval "${envtable[$this_module]}"; set +eu

			case "${#deps[@]}" in
				0 ) lets -l -i "$this_module doesn't have dependencies"
					return $s_ok ;;
				* ) lets -l -i "$this_module depends on: ${deps[@]}"
					are_in_modules ${deps[@]} || {
						lets -l -w "${deps[@]} not in MODULES"
					} ;;
			esac

			# Check if this module correctly defines its own
			# depmod. Return with an error if it doesn't since
			# other options rely on this module depmod.

			source "$module_d/$this_module/$module_sh"
			if ! declare -p -- "depmod" &>/dev/null; then
				lets -l -e "$this_module must define 'depmod'"
				return $s_err
			fi

			for dep in ${deps[@]}; do
				__is_in_array $dep ${depmod[@]} || {
					lets -l -e "$dep not in $this_module depmod: ${depmod[@]}"
					lets -l -e "add $dep to $this_module depmod"
					return $s_err
				}
			done
		)
		return $?
	fi

	(
		local -a files=( )
		local callback

		files+=( "$module_d/$this_module/$module_sh" )
		files+=( "$module_d/$this_module/$holder_sh" )
		files+=( "$module_d/$this_module/$scheme_sh" )

		if is_opt "doins" "upins" "upall" "doall" "watch"; then

			# Export external references
			if test_source <(echo "${envtable[$this_module]}"); then
				eval "${envtable[$this_module]}" || return $s_err2
			else
				return $s_err2
			fi
		fi

		# Source needed files
		if test_source "${files[@]}"; then
			for f in ${files[@]}; do source "$f" || return $s_err3; done
		else
			return $s_err3
		fi

		callback="$(declare -F -- "tod_$2" 2>/dev/null)" || return $s_err6

		if is_opt "doins" "doall"; then
			create_instance_d $instance_d || return $s_err4
		fi

		# -- Here be dragons
		eval "$callback \"${@:2}\"" || return $s_err5
	)
	case "$?" in
		$s_err2 ) lets -l -e "$this_module: failed to export environment" ;;
		$s_err3 ) lets -l -e "$this_module: failed to source $f"          ;;
		$s_err4 ) lets -l -e "$this_module: failed to create instance_d"  ;;
		$s_err5 ) lets -l -e "$this_module: $callback failed"             ;;
		$s_err6 ) lets -l -w "$this_module: $callback not available"
				  return $s_ok ;;
		$s_ok   ) return $s_ok ;;
	esac

	return $s_err
}

function __option_call
{
	local option="$1"; shift
	local -a mods=( "${@}" )
	local modname

	is_valid_module "${mods[@]}"
	case "$?" in
		$s_err | $s_off_broken ) return $s_err ;;
		$s_ok  | $s_off_usable ) ;;
	esac

	# Actually call into module code
	for modname in ${OPTARG[@]}; do
		__call_module $modname $option
		[ $? -eq $s_ok ] || return $s_err
	done
}

function option_call
{
	local -a mods

	mods=( $(get_modules_optarg "${@:2}") ) || return $s_err
	# Filtered out list of requested modules
	OPTARG=( "${mods[@]}" )

	__option_call "$1" "${mods[@]}" >/dev/null
}

# @desc   : process command line options only two options allowed per invocation
#         : at the moment. Keep it simple, keep it robust. For options details
#         : see help.sh.
#         :
#         : credits to https://stackoverflow.com/a/28466267
function __option_process
{
	local opt; OPTIND=1

	# Be quiet and disallow any single char option
	local -r options=":-:"
	local -a args

	if getopts "$options" opt; then
		if [ "$opt" = "-" ]; then
			opt="${OPTARG%%=*}"      # Get option name
			OPTARG="${OPTARG#$opt}"  # Get option argument(s)
			OPTARG="${OPTARG#=}"     # Drop `=` if any
			OPTARG="${OPTARG//,/ }"  # Drop `,` if any

			# Early return for help
			[ "$opt" = "help" ] && __help && return $s_ok

			is_in_options "$opt" || return $s_err2
		fi
	fi

	OPTIONS[$opt]=1; option_call $opt "${OPTARG[@]}"
	case "$?" in
		$s_err ) lets -l -e "$opt failed"; return $s_err        ;;
		$s_ok  ) lets -l -i --phew "$opt success"; return $s_ok ;;
	esac
}

function option_process
{
	__option_process ${@}
	case "$?" in
		$s_err2 ) lets -l -e "invalid option, --help" ;;
		$s_err  ) return $s_err                       ;;
		$s_ok   ) return $s_ok                        ;;
	esac
}
