#!/usr/bin/env bash
# audit_environment.sh — Audit shell environment and paths on macOS
# Output: JSON lines to stdout, one per finding
set -euo pipefail

json_escape() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g' | tr '\n' ' '; }

json_finding() {
  local severity="$1" finding action details
  finding=$(json_escape "$2")
  action=$(json_escape "$3")
  details=$(json_escape "$4")
  printf '{"module":"environment","severity":"%s","finding":"%s","action":"%s","details":"%s"}\n' \
    "$severity" "$finding" "$action" "$details"
}

# --- PATH analysis ---
IFS=':' read -ra path_dirs <<< "$PATH"
total_dirs=${#path_dirs[@]}

# Duplicate detection (compatible with bash 3)
duplicates=()
for i in "${!path_dirs[@]}"; do
  dir="${path_dirs[$i]}"
  is_dup=false
  for j in "${!path_dirs[@]}"; do
    if [ "$j" -lt "$i" ] && [ "${path_dirs[$j]}" = "$dir" ]; then
      is_dup=true
      break
    fi
  done
  if $is_dup; then
    duplicates+=("$dir")
  fi
done

if [ ${#duplicates[@]} -gt 0 ]; then
  dup_list=$(printf '%s, ' "${duplicates[@]}" | sed 's/, $//')
  json_finding "warning" "${#duplicates[@]} duplicate PATH entries" "deduplicate" "$dup_list"
else
  json_finding "info" "No duplicate PATH entries" "none" "${total_dirs} directories in PATH"
fi

# Non-existent directories
missing=()
for dir in "${path_dirs[@]}"; do
  if [ ! -d "$dir" ]; then
    missing+=("$dir")
  fi
done

if [ ${#missing[@]} -gt 0 ]; then
  missing_list=$(printf '%s, ' "${missing[@]}" | sed 's/, $//')
  json_finding "warning" "${#missing[@]} non-existent directories in PATH" "remove" "$missing_list"
fi

# --- Broken symlinks ---
broken_symlinks=()
for check_dir in /usr/local/bin "$HOME/.local/bin"; do
  if [ -d "$check_dir" ]; then
    while IFS= read -r link; do
      broken_symlinks+=("$link")
    done < <(find "$check_dir" -maxdepth 1 -type l ! -exec test -e {} \; -print 2>/dev/null || true)
  fi
done

if [ ${#broken_symlinks[@]} -gt 0 ]; then
  broken_list=$(printf '%s, ' "${broken_symlinks[@]}" | sed 's/, $//')
  json_finding "warning" "${#broken_symlinks[@]} broken symlinks found" "remove" "$broken_list"
else
  json_finding "info" "No broken symlinks in bin directories" "none" ""
fi

# --- Shell config analysis ---
shell_configs=()
for cfg in "$HOME/.zshrc" "$HOME/.zprofile" "$HOME/.zshenv" "$HOME/.bash_profile" "$HOME/.bashrc"; do
  if [ -f "$cfg" ]; then
    shell_configs+=("$(basename "$cfg")")
  fi
done
json_finding "info" "Shell configs found: ${shell_configs[*]}" "none" ""

# Check for PATH modifications across multiple files
path_mods=0
for cfg in "$HOME/.zshrc" "$HOME/.zprofile" "$HOME/.zshenv" "$HOME/.bash_profile" "$HOME/.bashrc"; do
  if [ -f "$cfg" ]; then
    count=$(grep -c -E 'export PATH|PATH=' "$cfg" 2>/dev/null || echo 0)
    count=$(echo "$count" | tr -d '[:space:]')
    path_mods=$((path_mods + count))
  fi
done

if [ "$path_mods" -gt 5 ]; then
  json_finding "warning" "PATH modified ${path_mods} times across shell configs" "consolidate" "Consider consolidating PATH modifications"
fi

# --- Environment variable checks ---
if [ -z "${ANTHROPIC_API_KEY:-}" ]; then
  json_finding "info" "ANTHROPIC_API_KEY not set" "none" "Set if using Claude API"
fi

if [ -n "${JAVA_HOME:-}" ] && [ ! -d "$JAVA_HOME" ]; then
  json_finding "warning" "JAVA_HOME points to non-existent directory" "fix" "$JAVA_HOME"
fi

# --- Shell startup time ---
if command -v zsh &>/dev/null; then
  startup_time=$( { time zsh -i -c exit; } 2>&1 | grep real | awk '{print $2}' || echo "unknown")
  # Parse the time - handle both formats like "0m0.123s" and "0.123"
  if echo "$startup_time" | grep -q 'm'; then
    seconds=$(echo "$startup_time" | sed 's/.*m//' | sed 's/s//')
  else
    seconds="$startup_time"
  fi

  if command -v python3 &>/dev/null; then
    is_slow=$(python3 -c "print('slow' if float('${seconds}') > 0.5 else 'ok')" 2>/dev/null || echo "ok")
  else
    is_slow="ok"
  fi

  if [ "$is_slow" = "slow" ]; then
    json_finding "warning" "Shell startup is slow (${startup_time})" "optimize" "Consider profiling with zsh -xv"
  else
    json_finding "info" "Shell startup time: ${startup_time}" "none" ""
  fi
fi
