#!/usr/bin/env bash
set -euo pipefail
cd -- "$(dirname -- "${BASH_SOURCE[0]}")"
source ./maximo-spaced-args.sh

check() {
    local label=$1 spec=$2 expected_count=$3 i
    shift 3
    local -a expected=("${@:1:expected_count}")
    shift "$expected_count"
    maximo_normalize_args "$spec" "$@"
    [[ ${#MAXIMO_NORMALIZED_ARGS[@]} == "$expected_count" ]] || {
        printf 'FAIL: %s (argument count)\n' "$label" >&2; exit 1;
    }
    for ((i=0; i<expected_count; i++)); do
        [[ ${MAXIMO_NORMALIZED_ARGS[i]} == "${expected[i]}" ]] || {
            printf 'FAIL: %s (argument %s)\n' "$label" "$i" >&2; exit 1;
        }
    done
    printf 'PASS: %s\n' "$label"
}

check 'spaced and attached values' '-m -o' 2 \
    '-m/tmp/input.xml' '-o/tmp/output.xml' \
    -m /tmp/input.xml -o/tmp/output.xml
check 'auto handles arbitrary option names' auto 4 \
    '-z/tmp/a b.xml' '-mtvalue' '-Q42' '-v' \
    -z '/tmp/a b.xml' -mt value -Q 42 -v
check 'auto preserves adjacent switches and attached paths' auto 4 \
    -v -m/tmp/input.xml -o/tmp/output.xml --help \
    -v -m/tmp/input.xml -o /tmp/output.xml --help
check 'auto preserves long options, empty values and negative numbers' auto 6 \
    --output file -m '' -n -1 --output file -m '' -n -1
check 'auto end-of-options' auto 3 -- -m file -- -m file
check 'auto exposes boolean-positional ambiguity' auto 1 -vfile -v file
check 'auto exposes attached-word ambiguity' auto 1 -tMAXDATAfile -tMAXDATA file
check 'auto preserves quoted metacharacters' auto 1 \
    '-z/tmp/a b/*;$(echo unsafe).xml' -z '/tmp/a b/*;$(echo unsafe).xml'
check 'auto no arguments' auto 0
check 'quoted paths and literal shell characters' '-m' 1 \
    '-m/tmp/a b/*;$(echo unsafe).xml' \
    -m '/tmp/a b/*;$(echo unsafe).xml'
check 'boolean and unknown switches stay separate' '-m' 4 \
    -v --unknown input '-mfile' \
    -v --unknown input -m file
check 'repeated values and case sensitivity' '-m' 4 \
    -mfirst -msecond -M third \
    -m first -m second -M third
check 'multi-character options and boolean prefixes' '-mt' 2 \
    -m -mtvalue -m -mt value
check 'end-of-options marker' '-m' 4 -- -m file '' -- -m file ''
check 'no arguments' '-m' 0
check 'empty option list preserves arguments' '' 2 -m file -m file
check 'attached negative value' '-m' 1 -m-1 -m-1
check 'dash-leading filename made relative' '-m' 1 '-m./-file' -m ./-file

for scenario in missing empty switch; do
    case $scenario in
        missing) set -- -m ;;
        empty) set -- -m '' ;;
        switch) set -- -m -v ;;
    esac
    if maximo_normalize_args '-m' "$@" 2>/dev/null; then
        printf 'FAIL: accepted %s value\n' "$scenario" >&2; exit 1
    else
        [[ $? == 2 && ${#MAXIMO_NORMALIZED_ARGS[@]} == 0 ]]
    fi
done
printf 'PASS: missing, empty and ambiguous values rejected\n'

if maximo_normalize_args '--long' value 2>/dev/null; then
    printf 'FAIL: accepted unsupported option specification\n' >&2; exit 1
fi

# Exercise the executable mode without launching any IBM code.
output=$(bash ./maximo-spaced-args.sh '-m' printf '<%s>\n' -m '/tmp/a b.xml')
[[ $output == '<-m/tmp/a b.xml>' ]]
if bash ./maximo-spaced-args.sh '-m' bash -c 'exit 17'; then
    printf 'FAIL: lost child exit status\n' >&2; exit 1
else
    [[ $? == 17 ]]
fi
printf 'PASS: executable mode preserves quoting and exit status\n'

# Model the injected launcher: normalize once, restore "$@", forward to Java.
launcher() {
    maximo_normalize_args '-m' "$@" || return "$?"
    set -- "${MAXIMO_NORMALIZED_ARGS[@]}"
    [[ $# == 1 && $1 == '-m/tmp/a b.xml' ]]
}
launcher -m '/tmp/a b.xml'
printf 'PASS: injected launcher forwards a single quoted argument\n'
