#!/usr/bin/env bash
# toolkit module: ide/01_hints.sh
# IDE code completion support for BashSupport Pro

declare -g __radp_ide_hints_file=""

#######################################
# Initialize IDE hints file
# Generates _idecomp.sh with framework and user sources
# This enables BashSupport Pro to provide code completion
# for framework functions, variables, user variables, and user libs
#
# The generated file uses absolute paths (machine-specific)
# and should be added to .gitignore
#
# Globals:
#   gr_fw_user_config_path - user config directory
#   gr_fw_context_vars_path - framework vars directory
#   gr_fw_config_file - framework config file
#   gr_fw_context_libs_path - framework libs directory
#   gr_fw_user_config_file - user config file (contains gr_radp_extend_* vars)
#   gra_radp_fw_user_lib_paths - user libs directories array
# Returns:
#   0 - success
#######################################
radp_ide_init() {
  # Only generate if user config directory exists and is writable.
  # For read-only installations (e.g. RPM under /usr/lib64), skip generation
  # as IDE hints are not useful on headless systems anyway.
  [[ ! -d "$gr_fw_user_config_path" ]] && return 0
  [[ ! -w "$gr_fw_user_config_path" ]] && return 0

  __radp_ide_hints_file="$gr_fw_user_config_path/_idecomp.sh"
  __radp_ide_generate_hints_file

  # Also write a copy into the framework context cache directory so that
  # toolkit scripts can add a shellcheck source directive pointing to it,
  # enabling BashSupport Pro code completion during development.
  if [[ -d "$gr_fw_context_cache_path" && -w "$gr_fw_context_cache_path" ]]; then
    cp "$__radp_ide_hints_file" "$gr_fw_context_cache_path/_idecomp.sh"
  fi
}

#######################################
# Add commands directory sources to hints file
# Arguments:
#   1 - commands_dir: absolute path to commands directory
#######################################
radp_ide_add_commands_dir() {
  local commands_dir="$1"

  [[ ! -f "$__radp_ide_hints_file" ]] && return 0
  [[ ! -d "$commands_dir" ]] && return 0

  # Check if already added
  grep -q "# User commands" "$__radp_ide_hints_file" 2>/dev/null && return 0

  __radp_ide_append_sources "$commands_dir" "User commands"
}

#######################################
# Internal: Generate the base hints file
# Outputs:
#   Writes _idecomp.sh to user config directory
#######################################
__radp_ide_generate_hints_file() {
  cat >"$__radp_ide_hints_file" <<'EOF'
#!/usr/bin/env bash
set -e

########################################################################################################################
###
# IDE Navigation Hints (auto-generated by radp-bash-framework)
# This file provides code completion for BashSupport Pro IDE plugin
#
# DO NOT commit this file to git - add to .gitignore
# Regenerate by running your CLI tool once (e.g., homelabctl --help)
#
# Contents:
#   - Framework global variables (gr_fw_*, gr_radp_fw_*)
#   - Framework library functions (radp_*)
#   - User global variables (gr_radp_extend_*)
#   - User library functions
########################################################################################################################
__ide_hints() {
EOF

  # 1. Framework global vars (all .sh under vars/)
  if [[ -d "$gr_fw_context_vars_path" ]]; then
    printf '\n  # Framework global vars\n' >>"$__radp_ide_hints_file"
    local -a fw_vars=()
    mapfile -t fw_vars < <(find "$gr_fw_context_vars_path" -type f -name "*.sh" | sort)
    local fw_var
    for fw_var in "${fw_vars[@]}"; do
      printf '  # shellcheck source=%s\n' "$fw_var" >>"$__radp_ide_hints_file"
    done
  fi
  printf '  # shellcheck source=%s\n' "$gr_fw_config_file" >>"$__radp_ide_hints_file"

  # 2. Framework libs
  if [[ -d "$gr_fw_context_libs_path" ]]; then
    printf '\n  # Framework libs\n' >>"$__radp_ide_hints_file"
    local -a fw_libs=()
    mapfile -t fw_libs < <(find "$gr_fw_context_libs_path" -type f -name "*.sh" | sort -t '_' -k 1,1n)
    local fw_lib
    for fw_lib in "${fw_libs[@]}"; do
      printf '  # shellcheck source=%s\n' "$fw_lib" >>"$__radp_ide_hints_file"
    done
  fi

  # 3. User config file (contains gr_radp_extend_* vars)
  if [[ -f "$gr_fw_user_config_file" ]]; then
    printf '\n  # User config (user global vars: gr_radp_extend_*)\n' >>"$__radp_ide_hints_file"
    printf '  # shellcheck source=%s\n' "$gr_fw_user_config_file" >>"$__radp_ide_hints_file"
  fi

  # 4. User libs (iterate over all paths in the array)
  printf '\n  # User libs\n' >>"$__radp_ide_hints_file"
  local lib_path
  for lib_path in "${gra_radp_fw_user_lib_paths[@]}"; do
    [[ -z "$lib_path" ]] && continue
    [[ ! -d "$lib_path" ]] && continue
    local -a user_libs=()
    mapfile -t user_libs < <(find "$lib_path" -type f -name "*.sh" | sort -t '_' -k 1,1n)
    local user_lib
    for user_lib in "${user_libs[@]}"; do
      printf '  # shellcheck source=%s\n' "$user_lib" >>"$__radp_ide_hints_file"
    done
  done

  cat >>"$__radp_ide_hints_file" <<'EOF'
  :
}

__ide_hints
EOF
}

#######################################
# Internal: Append sources to hints file
# Arguments:
#   1 - directory: source directory
#   2 - section_name: section comment name
#######################################
__radp_ide_append_sources() {
  local directory="$1"
  local section_name="$2"

  local -a files=()
  mapfile -t files < <(find "$directory" -type f -name "*.sh" | sort)
  [[ ${#files[@]} -eq 0 ]] && return 0

  # Remove closing lines and append new section
  # Remove last 4 lines (  :\n}\n\n__ide_hints\n)
  local tmp_file total_lines keep_lines
  tmp_file=$(mktemp)
  total_lines=$(wc -l <"$__radp_ide_hints_file")
  keep_lines=$((total_lines - 4))
  head -n "$keep_lines" "$__radp_ide_hints_file" >"$tmp_file"

  {
    printf '\n  # %s\n' "$section_name"
    for file in "${files[@]}"; do
      printf '  # shellcheck source=%s\n' "$file"
    done
    printf '  :\n}\n\n__ide_hints\n'
  } >>"$tmp_file"

  mv "$tmp_file" "$__radp_ide_hints_file"
}
