.just

if [ -z "${VSI_COMMON_DIR+set}" ]; then
  VSI_COMMON_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.."; pwd)"
fi

source "${VSI_COMMON_DIR}/linux/just_files/just_common.bsh"
source "${VSI_COMMON_DIR}/linux/isin"
source "${VSI_COMMON_DIR}/linux/dir_tools.bsh"
source "${VSI_COMMON_DIR}/linux/elements.bsh"

_just()
{
  local JUST_PLUGINS=()
  local just_plugin
  local i

  shopt -s extglob # Why is this needed?

  COMPREPLY=() # Array variable storing the possible completions.

  # $1 - command aka $0
  # $2 - current word; can be "" if you just typed a space
  # $3 - last word completed
  # COMP_WORDS - All args

  # Emulate how the just systems finds all of its help files

  # 1. Initial files: just_functions.bsh
  local JUST_HELP_FILES=(${JUST_HELP_FILES[@]+"${JUST_HELP_FILES[@]}"})
  if [ "${JUST_HELP_FILES+set}" != "set" ]; then
    JUST_HELP_FILES=("${VSI_COMMON_DIR}/linux/just_files/just_functions.bsh")
  fi

  # 2. Find Justfile, load it, and copy the JUST_HELP_FILES array
  local just_files="$(
    _just_load_justfile "${JUSTFILE-Justfile}" &> /dev/null
    join_a just_files ${JUST_HELP_FILES[@]+"${JUST_HELP_FILES[@]}"}
    echo "${just_files}"
  )"
  split_s just_files "${just_files}"
  JUST_HELP_FILES=(${just_files[@]+"${just_files[@]}"})

  # 3. Emulate finding and adding plugins
  # _just_load_justfile should have made the Justfile the first entry in JUST_HELP_FILES
  local just_dir="$(dirname "${JUST_HELP_FILES[0]}")"
  _just_get_plugins "${just_dir}"
  for just_plugin in ${JUST_PLUGINS[@]+"${JUST_PLUGINS[@]}"}; do
    JUST_HELP_FILES+=("${just_plugin}")
  done

  # Get all command info once
  local parsed_help_a
  _just_parse_helps ${JUST_HELP_FILES[@]+"${JUST_HELP_FILES[@]}"}
  # Get just command names and remove the comments
  parsed_help_a=("${parsed_help_a[@]%% ${JUST_HELP_SEPARATOR}*}")

  # Get main commands only
  local just_commands=()
  while IFS= read -r -d '' i || [ -n "${i}" ]; do
    # Remove all entries containing an _, and sort them and remove duplicates
    if [[ ${i} != *_* ]]; then
      just_commands+=("${i}")
    fi
  done < <(MIFS='\\x00' join_a_out "${parsed_help_a[@]}" | sort -u -z)

  # Get sub_commands
  local just_subcommands
  #WARNING: Susceptible to wildcard expansion (what if a subcommand is literal *)
  just_subcommands=($(IFS=$'\n'; (_just_subcommands_from_array | sort -u ) <<< "${parsed_help_a[*]}"))

  # Declare here so I can use it in .just plugin
  local just_subtargets=()

  # Call local .just if it exists. Starts with checking the Justfile, and
  # then all plugin directories
  local sourced_dotjusts=()
  for i in ${JUST_HELP_FILES[@]+"${JUST_HELP_FILES[@]}"}; do
    i="$(dirname "${i}")"
    if [ -f "${i}/.just" ]; then
      # Skip duplicates
      if isin "${i}/.just" ${sourced_dotjusts[@]+"${sourced_dotjusts[@]}"}; then
        continue
      fi
      sourced_dotjusts+=("${i}/.just")
      source "${i}/.just"
      if [ -n "${JUST_RETURN+set}" ]; then
        local just_return="${JUST_RETURN}"
        unset JUST_RETURN
        return ${just_return}
      fi
    fi
  done

  # If the last word completed is a subcommand, only match subtargets
  if isin "${3}" ${just_subcommands[@]+"${just_subcommands[@]}"}; then
    _just_subtargets_from_array "${3}" ${parsed_help_a[@]+"${parsed_help_a[@]}"}
    #WARNING: Susceptible to wildcard expansion (what if a subtarget is literal *)
    COMPREPLY+=($(\compgen -W "${just_subtargets+${just_subtargets[*]}}" -- ${2}))
    return 0
  fi

  # Search for the last subcommand used. If a match is found, add it to the total
  # list of just_commands
  for (( i=${#COMP_WORDS[@]}-1; i>0; i--)); do
    if isin "${COMP_WORDS[i]}" "${just_subcommands[@]}"; then
      _just_subtargets_from_array "${COMP_WORDS[i]}" ${parsed_help_a[@]+"${parsed_help_a[@]}"}
      just_commands+=(${just_subtargets[@]+"${just_subtargets[@]}"})
      break
    fi
  done

  # Simply just auto complete all commands
  #WARNING: Susceptible to wildcard expansion (what if a command is literal *)
  COMPREPLY+=($(\compgen -o bashdefault -W "${just_commands+${just_commands[*]}} ${just_subcommands+${just_subcommands[*]}}" -- ${2}))

  return 0
}

if ! command -v compopt &> /dev/null; then
  # While this won't allow compopt to behave the way we always want on bash 3.2
  # It's the best "default" behavior
  complete -o default -F _just just
else
  complete -F _just just
fi