# -*- shell-script -*-

_astra_settings_exchange()
{
  compopt +o default

  local cur prev words cword split prefix
  _init_completion -s -n : || return

  if [[ $cword == 1 ]]; then

    if [[ $cur == -* ]]; then
      COMPREPLY=($(compgen -W '$(_parse_help "$1" --help)' -- "$cur"))
    else
      compopt -o default
      COMPREPLY=()
    fi

  elif [[ $cword == 2 ]]; then

    local modules=($("$1" -m 2>/dev/null | sort))
    if [[ $prev == -o || $prev == --options ]]; then
      # The -o (--options) option supports specifying a list of modules,
      # but since the delimiter is a semicolon, this feature is not
      # implemented here, only the name of one module is completed.
      COMPREPLY=($(compgen -W "${modules[*]}" -- "$cur"))
    elif [[ $prev == -* ]]; then
      COMPREPLY=()
    else
      local groups=($("$1" -g 2>/dev/null | sort))
      if [[ $cur == *:* ]]; then
        local prefix=${cur%:*}
        cur=${cur##*:}

        local selectedModules=()
        IFS=$':\n' read -ra selectedModules <<< "$prefix"
        for module in ${selectedModules[@]}; do
          if [[ ${groups[@]} =~ $module ]]; then
            COMPREPLY=()
            return 0
          fi
        done

        local unselectedModules=()
        for module in ${modules[@]}; do
          if ! [[ ${selectedModules[@]} =~ $module ]]; then
            unselectedModules+=($module)
          fi
        done

        if [[ ${#unselectedModules[*]} == 0 ]]; then
          COMPREPLY=()
        else
          COMPREPLY=($(compgen -W "${unselectedModules[*]}" -- "$cur"))
          if [[ ${#COMPREPLY[*]} == 1 ]]; then
            if [[ $cur == ${COMPREPLY[0]} ]]; then
              COMPREPLY=("${COMPREPLY[0]}:")
            fi
            if [[ ${#unselectedModules[*]} -gt 1 ]]; then
              compopt -o nospace
            fi
          fi
        fi
      else
        COMPREPLY=($(compgen -W "${groups[*]} ${modules[*]}" -- "$cur"))
        if [[ ${#COMPREPLY[*]} == 1 && ${modules[@]} =~ ${COMPREPLY[0]} ]]; then
          if [[ $cur == ${COMPREPLY[0]} ]]; then
            COMPREPLY=("${COMPREPLY[0]}:")
          fi
          compopt -o nospace
        fi
      fi
    fi

  elif [[ $cword -gt 2 ]]; then

    if [[ ${words[@]} == -* ]]; then
      COMPREPLY=()
    else
      local modules=($("$1" -m 2>/dev/null | sort))
      local groups=($("$1" -g 2>/dev/null | sort))

      local selectedModules=()
      IFS=$':\n' read -ra selectedModules <<< "${words[2]}"

      if [[ ${#selectedModules[*]} -gt 1 || ${groups[@]} =~ ${selectedModules[0]} ]]; then
        if [[ ${#selectedModules[*]} -gt 1 ]]; then
          for module in ${selectedModules[@]}; do
            if [[ ${groups[@]} =~ $module ]]; then
              COMPREPLY=()
              return 0
            fi
          done
        else
          selectedModules=($(LANG=C "$1" -p 2>/dev/null                          \
                             | grep -e '^[^ ]' -e 'Group:'                       \
                             | sed -e '/^ /s/^.*Group: \(.*$\)/\1@/' -e 's/:/ /' \
                             | tr -d '\n'                                        \
                             | tr '@' '\n'                                       \
                             | grep "${selectedModules[0]}"                      \
                             | cut -d' ' -f1                                     \
                             | sort))
        fi

        local options=($("$1" -o "$(echo ${selectedModules[@]} | tr ' ' ';')" 2>/dev/null | sort))
        local selectedOptions=(${words[@]:3})
        local unselectedOptions=()
        for option in ${options[@]}; do
          if ! [[ ${selectedOptions[@]} =~ $option ]]; then
            unselectedOptions+=($option)
          fi
        done

        COMPREPLY=($(compgen -W "${unselectedOptions[*]}" -- "$cur"))

        __ltrim_colon_completions "$cur"

      else

        local options=($("$1" -o "${selectedModules[0]}" 2>/dev/null | sed 's/^.*://' | sort))
        local selectedOptions=(${words[@]:3})
        local unselectedOptions=()
        for option in ${options[@]}; do
          if ! [[ ${selectedOptions[@]} =~ $option ]]; then
            unselectedOptions+=($option)
          fi
        done

        COMPREPLY=($(compgen -W "${unselectedOptions[*]}" -- "$cur"))

      fi
    fi

  fi
} && complete -F _astra_settings_exchange astra-settings-{export,import,merge,remove}
