#!/usr/bin/env bash
set -euo pipefail

declare -A VISITED

TREE_TEMP=$(mktemp)
BODY_TEMP=$(mktemp)

trap 'rm -f "$TREE_TEMP" "$BODY_TEMP"' EXIT

# ----------------------------
# Helpers
# ----------------------------

strip_colors() {
  sed -E "s/\x1B\[[0-9;]*[mK]//g"
}

run_help() {
 local project="./RackPeek" 
 local config="Release" 
 local publish_dir="$project/publish" 
 local exe="$publish_dir/RackPeek"

  if [[ ! -x "$exe" ]]; then
    echo "Publishing RackPeek ($config)..." >&2
    dotnet publish "$project" -c "$config" -o "$publish_dir" --self-contained false -p:PublishSingleFile=true >&2
  fi

  local output
  output=$("$exe" "$@" 2>&1 | strip_colors)
  echo "$output"
}

# UPDATED: Handles descriptions that start on the next line
get_description() {
  local help_output="$1"
  echo "$help_output" | awk '
    # If we find the header...
    /^DESCRIPTION:/ {
      in_desc = 1
      # Remove the header itself
      sub(/^DESCRIPTION:[[:space:]]*/, "")
      
      # If there is text on this same line, print it and quit
      if (length($0) > 0) {
        print $0
        exit
      }
      next
    }

    # If we are inside the description block...
    in_desc {
      # Stop if we hit an empty line or the next Section (UPPERCASE:)
      if (/^[[:space:]]*$/) exit
      if (/^[A-Z]+:/) exit

      # Trim leading/trailing whitespace
      gsub(/^[[:space:]]+|[[:space:]]+$/, "")
      
      # Print the line (we only take the first non-empty line for the index)
      print $0
      exit
    }
  '
}

# UPDATED: Handles "add <name>" correctly by taking only the first column ($1)
get_child_commands() {
  local help_output="$1"
  
  echo "$help_output" | awk '
    BEGIN { in_commands = 0 }
    /^COMMANDS:/ { in_commands = 1; next }
    
    in_commands {
      # Stop if we hit an empty line or a new section
      if ($0 ~ /^[[:space:]]*$/) exit;
      if ($0 ~ /^[A-Z]+:/) exit;

      # Match lines that look like commands (indented)
      if ($0 ~ /^[[:space:]]+[a-zA-Z0-9-]+/) {
        # Print only the first word (the command name)
        print $1
      }
    }
  '
}

# ----------------------------
# Recursion
# ----------------------------

generate_help_recursive() {
  local path_string="$1"
  
  # Convert string to array for the run_help command
  local current_cmd_array=()
  if [[ -n "$path_string" ]]; then
    IFS=' ' read -r -a current_cmd_array <<< "$path_string"
  fi

  local map_key="${path_string:-root}"
  
  if [[ -n "${VISITED["$map_key"]:-}" ]]; then return; fi
  VISITED["$map_key"]=1

  # 1. Run Help
  local help_output
  if ! help_output=$(run_help "${current_cmd_array[@]}" --help); then
    echo "Skipping: $map_key (help failed)" >&2
    return
  fi

if is_invalid_help "$help_output"; then
  echo "Skipping: $map_key (invalid command)" >&2
  return
fi


  # 2. Extract Description
  local description
  description=$(get_description "$help_output")
  
  # 3. Build Tree Entry
  local depth=${#current_cmd_array[@]}
  local indent=""
  [[ $depth -gt 0 ]] && printf -v indent "%*s" $((depth * 2)) ""
  
  local tree_label
  [[ $depth -eq 0 ]] && tree_label="rpk" || tree_label="${current_cmd_array[-1]}"

  local anchor_text="rpk $path_string"
  anchor_text="${anchor_text% }" 
  local anchor_link=$(echo "$anchor_text" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')

  # Format: - [label](link) - Description
  local tree_entry="${indent}- [${tree_label}](docs/Commands.md#${anchor_link})"
  if [[ -n "$description" ]]; then
    tree_entry="${tree_entry} - ${description}"
  fi
  
  echo "$tree_entry" >> "$TREE_TEMP"

  # 4. Write Body
  local display_header
  [[ -z "$path_string" ]] && display_header="rpk" || display_header="rpk $path_string"

  {
    echo "## \`${display_header}\`"
    echo '```'
    echo "$help_output"
    echo '```'
    echo ""
  } >> "$BODY_TEMP"

  # 5. Recurse
  local child_cmds
  mapfile -t child_cmds < <(get_child_commands "$help_output")

  for child in "${child_cmds[@]}"; do
    echo "Recursing into: ${display_header} ${child}" >&2
    local next_path
    if [[ -z "$path_string" ]]; then
      next_path="$child"
    else
      next_path="$path_string $child"
    fi
    generate_help_recursive "$next_path"
  done
}

is_invalid_help() {
  local output="$1"

  # Detect common failure patterns
  if echo "$output" | grep -qiE \
    "Unknown command|CommandParseException|Unexpected error occurred"; then
    return 0
  fi

  return 1
}


# ----------------------------
# Main
# ----------------------------

echo "Generating documentation..."

generate_help_recursive ""

{
  echo ""
  cat "$TREE_TEMP"
} > "Shared.Rcl/wwwroot/raw_docs/CommandIndex.md"

{
  echo "# CLI Commands"
  echo ""
  cat "$BODY_TEMP"
} > "Shared.Rcl/wwwroot/raw_docs/Commands.md"

echo "Generated Successfully."