#!/usr/bin/env bash

set -o nounset -o noglob +o braceexpand
shopt -s lastpipe
unset CDPATH TMOUT
declare -r -x LC_ALL='C.UTF-8'

main () {

  declare -g -i test_count=0
  declare -g -i error_count=0

  trap exit_trap EXIT

  printf 'CTRL-C to end test\n'

  local declaration
  if (( ${#} == 0 )) then
    declaration='local -A assoc
  '
  else
    declaration="${1} -A "
  fi

  while true; do
    (( ++test_count ))
    printf '%s\r' "test ${test_count}"

    # Create an associative array compound assignment containing random-length
    # quoted arrays, unquoted scalars, and literals

    local -i array_count=0
    local -i scalar_count=0

    local script="\
set -o nounset -o noglob +o braceexpand
shopt -s lastpipe
unset CDPATH TMOUT
declare -r -x LC_ALL='C.UTF-8'

main () {

"

    local test_case=''

    local assignment_contents=''

    while (( ( SRANDOM & 7 ) > 0 )) do

      local -i type_selector="$(( SRANDOM & 32767 ))"
      if (( type_selector < 10923 )) then
        assignment_contents+=" '${SRANDOM//[01]/& }'"
      else
        local -a list=()
        local -i element_count
        for (( element_count = SRANDOM & 7; element_count > 0; --element_count )) do
          list+=( "${SRANDOM}" )
        done
        if (( type_selector < 21845 )) then
          local array_name="array_$(( array_count++ ))"
	  list=( "${list[@]//[01]/& }" )
          test_case+="  local -a ${array_name}=( ${list[*]@Q} )"$'\n'
          assignment_contents+=" \"\${${array_name}[@]}\""
        else
          local scalar_name="scalar_$(( scalar_count++ ))"
          test_case+="  local ${scalar_name}='${list[*]}'"$'\n'
          assignment_contents+=" \${${scalar_name}}"
        fi
      fi

    done

    test_case+="\

  ${declaration}assoc=(${assignment_contents} )
  set --${assignment_contents}"

    script+="${test_case}"'

  breakage="false"
  if (( ( ( ${#} + 1 ) / 2 ) != ${#assoc[@]} )) then
    breakage="true"
  fi
  while [[ ${breakage} == "false" && ${#} -gt 1 ]] do
    if [[ ${assoc[${1}]} != "${2}" ]] then
      breakage="true"
    fi
    shift 2
  done
  if [[ ${breakage} == "false" && ${#} -eq 1 && -n ${assoc[${1}]} ]] then
    breakage="true"
  fi
  [[ ${breakage} == "false" ]]
  exit

}

main
'

    if ! ./bash -c "${script}"; then
      (( ++error_count ))
      printf '========\n'
      printf '%s\n' "${test_case}"
      printf '========\n'
    fi

  done

}

exit_trap () {
  printf '%s\n' "${test_count} tests"
  printf '%s\n' "${error_count} errors"
}

main "${@}"
