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

required=(
  KAFKA_BOOTSTRAP_SERVER
  KAFKA_CONSUMER_GROUPS_COMMAND
  KAFKA_POLICY_ID
  KAFKA_GROUP_PREFIX
  KAFKA_GROUP_PATTERN
  KAFKA_TIMESTAMP_CAPTURE_GROUP
  KAFKA_INACTIVE_STATES
  KAFKA_MINIMUM_AGE_HOURS
  KAFKA_CANDIDATE_LIMIT
  KAFKA_DELETE_BATCH_SIZE
  KAFKA_COMMAND_TIMEOUT_SECONDS
)
for name in "${required[@]}"; do
  if [[ -z "${!name:-}" ]]; then
    printf '{"ok":false,"error":"missing-required-config","field":"%s"}\n' "$name"
    exit 2
  fi
done

groups_cli=("$KAFKA_CONSUMER_GROUPS_COMMAND" --bootstrap-server "$KAFKA_BOOTSTRAP_SERVER")
now_ms="$(( $(date +%s) * 1000 ))"
minimum_age_ms="$(( KAFKA_MINIMUM_AGE_HOURS * 60 * 60 * 1000 ))"
selected=0
deleted=0
failed=0
scanned=0
prefix_matched=0
pattern_matched=0
age_matched=0
inactive_matched=0

state_allowed() {
  local state="$1"
  local allowed
  IFS=',' read -r -a states <<<"$KAFKA_INACTIVE_STATES"
  for allowed in "${states[@]}"; do
    [[ "$state" == "$allowed" ]] && return 0
  done
  return 1
}

declare -A group_states=()
while read -r group state; do
  [[ -n "$group" && -n "$state" ]] || continue
  group_states["$group"]="$state"
done < <(
  timeout "$KAFKA_COMMAND_TIMEOUT_SECONDS" "${groups_cli[@]}" --describe --all-groups --state 2>/dev/null |
    awk 'NF >= 2 && $1 != "GROUP" { print $1, $(NF-1) }'
)

selected_groups=()

while IFS= read -r group; do
  [[ -n "$group" ]] || continue
  scanned=$((scanned + 1))
  [[ "$group" == "$KAFKA_GROUP_PREFIX"* ]] || continue
  prefix_matched=$((prefix_matched + 1))
  [[ "$group" =~ $KAFKA_GROUP_PATTERN ]] || continue
  pattern_matched=$((pattern_matched + 1))
  created_ms="${BASH_REMATCH[$KAFKA_TIMESTAMP_CAPTURE_GROUP]:-}"
  [[ "$created_ms" =~ ^[0-9]{13}$ ]] || continue
  (( now_ms - created_ms >= minimum_age_ms )) || continue
  age_matched=$((age_matched + 1))
  (( selected < KAFKA_CANDIDATE_LIMIT )) || continue

  state="${group_states[$group]:-}"
  state_allowed "$state" || continue
  inactive_matched=$((inactive_matched + 1))
  selected=$((selected + 1))
  selected_groups+=("$group")
done < <(timeout "$KAFKA_COMMAND_TIMEOUT_SECONDS" "${groups_cli[@]}" --list 2>/dev/null)

delete_args=()
delete_count="${#selected_groups[@]}"
(( delete_count <= KAFKA_DELETE_BATCH_SIZE )) || delete_count="$KAFKA_DELETE_BATCH_SIZE"
for ((index = 0; index < delete_count; index += 1)); do
  delete_args+=(--group "${selected_groups[$index]}")
done
if (( delete_count > 0 )); then
  timeout "$KAFKA_COMMAND_TIMEOUT_SECONDS" "${groups_cli[@]}" --delete "${delete_args[@]}" >/dev/null 2>&1 || true
  declare -A remaining_groups=()
  while IFS= read -r group; do
    [[ -n "$group" ]] && remaining_groups["$group"]=1
  done < <(timeout "$KAFKA_COMMAND_TIMEOUT_SECONDS" "${groups_cli[@]}" --list 2>/dev/null)
  for ((index = 0; index < delete_count; index += 1)); do
    if [[ -n "${remaining_groups[${selected_groups[$index]}]:-}" ]]; then
      failed=$((failed + 1))
    else
      deleted=$((deleted + 1))
    fi
  done
fi

printf '{"ok":%s,"policy":"%s","scanned":%d,"prefixMatched":%d,"patternMatched":%d,"ageMatched":%d,"inactiveMatched":%d,"selected":%d,"deleted":%d,"failed":%d,"valuesPrinted":false}\n' \
  "$([[ "$failed" -eq 0 ]] && printf true || printf false)" \
  "$KAFKA_POLICY_ID" "$scanned" "$prefix_matched" "$pattern_matched" "$age_matched" \
  "$inactive_matched" "$selected" "$deleted" "$failed"
[[ "$failed" -eq 0 ]]
