#!/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" )

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

			# Only upmod doesn't need scheme
			files+=( "$module_d/$this_module/$scheme_sh" )

			# 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
}
