# -*- shell-script -*-

################################################################################

§class "rule" --with-interface --properties "name" "match:a" 

§function.clone "§rule.set_match" "§rule._set_match"

bashrun_rules_applied=0

################################################################################

function §rule.set_match {

    eval "$(§rule.get_match matches)"

    if [[ ${#matches[*]} -eq 0 ]]; then
	matches=("$@")
    else
	matches=("${matches[@]}" "$@")
    fi
    §rule._set_match "${matches[@]}"
}

function §rules.apply {

    §command.get_word

    [[ bashrun_rules_applied -eq 1 ]] && return 0

    local action=$(§actions.current)
    local word="$bashrun_command_word"
    local command="$bashrun_command"
    local rules rule match spec regexp 

    # move the term-run rule to the end of rules
    local rules="$(§rules.all)"
    rules="${rules/term-run/} term-run"

    §debug "applying rules..."

    for rule in $rules; do
	§rules.seek "$rule"
	eval "$(§rule.get_match match)"

	# implicitly add all terminal --match progs to the end of
	# the term-run rule:
	if [[ "$rule" == "term-run" ]]; then
	    eval "$(§terminals.get_match terminals_match)"
	    match=( "${match[@]}" "${terminals_match[@]}" )
	fi

	for spec in "${match[@]}"; do

	    if [[ "$word" == "$spec" ]]; then
		# literal match

		§debug -v "$word" "==" -v "$spec" "->" -y "$rule"
		bashrun_rules_applied=1

		if §actions.seek "$rule"; then
		    §action.run
		fi
		return 0
	    else
		if [[ "$spec" =~ /.+/ ]]; then
		    # regexp given
		    regexp=${spec:1:${#spec}-2}

		    # match the whole command against regexp
		    if [[ "$command" =~ $regexp ]]; then
			# regexp match
		
			§debug -v "'$command'" "=~" -v "$spec" \
			          "->" -y "$rule"
			bashrun_rules_applied=1

			if §actions.seek "$rule"; then
			    §action.run
			fi
			return 0
		    fi
		fi
	    fi
	done
    done
    §rules.seek_start

    # run in terminal if this command is linked against a console library
    if [[ "$(type -t $word)" == "file" ]]; then

	local libs="n?cursesw?|slang|termbox|rhtv|newt|aa"

	if [[ "$(ldd $(which $word))" =~ (lib($libs)\.(so|a)[^ ]+) ]]; then

	    §debug -v "$word" "is linked against" \
		-v "${BASH_REMATCH[1]}" "->" -y "term-run" 
	    
	    §actions.seek "term-run"
	    §action.run
	    return 0
	fi
    fi

    # no rule applied if we end up here
    return 1
}

function §rules.applied? {

    [[ bashrun_rules_applied -eq 1 ]] && return 0
    [[ bashrun_rules_applied -eq 0 ]] && return 1
}

