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

REDIS_HOST="${REDIS_HOST:-dev.ellisbs.co.uk}"
REDIS_PORT="${REDIS_PORT:-6379}"
REDIS_PASSWORD="${REDIS_PASSWORD:-}"
DEBUG="${DEBUG:-1}"

usage() {
  echo "Usage: REDIS_PASSWORD=pass ./explore_redis_nc.sh [--host HOST] [--port PORT] [--debug|--no-debug]"
}

while [[ $# -gt 0 ]]; do
  case "$1" in
  --host)
    shift
    REDIS_HOST="$1"
    ;;
  --port)
    shift
    REDIS_PORT="$1"
    ;;
  --password)
    shift
    REDIS_PASSWORD="$1"
    ;;
  --debug) DEBUG=1 ;;
  --no-debug) DEBUG=0 ;;
  -h | --help)
    usage
    exit 0
    ;;
  *)
    echo "Unknown arg $1"
    usage
    exit 1
    ;;
  esac
  shift
done

[[ -z $REDIS_PASSWORD ]] && {
  echo "Need REDIS_PASSWORD env or --password"
  exit 1
}

dlog() { [[ $DEBUG == "1" ]] && echo "$*"; }

# RESP encoder
resp() {
  local out="*${#@}\r\n"
  for arg; do
    out+="$${#arg}\r\n${arg}\r\n"
  done
  printf "%s" "$out"
}

# Send a command and dump raw response
redis_raw() {
  local req
  req="$(resp "$@")"
  printf "%s" "$req" | nc -w 3 "$REDIS_HOST" "$REDIS_PORT"
}

# Convenience wrapper: AUTH once per call
redis_cmd() {
  {
    resp AUTH "$REDIS_PASSWORD"
    resp "$@"
  } | nc -w 3 "$REDIS_HOST" "$REDIS_PORT"
}

# ---- Connect & PING
dlog "Attempting to connect to Redis at $REDIS_HOST:$REDIS_PORT"
dlog "Password length: ${#REDIS_PASSWORD}, first/last: ${REDIS_PASSWORD:0:1}...${REDIS_PASSWORD: -1}"
pong="$(redis_cmd PING | tr -d '\r')"
if ! grep -q "+PONG" <<<"$pong"; then
  echo "Connection failed: $pong"
  exit 1
fi
echo "Successfully connected to Redis!"

# ---- List keys
keys_resp="$(redis_cmd KEYS '*')"
# Parse array: lines beginning with $len / value
mapfile -t keys < <(echo "$keys_resp" | awk '/^\$/ {getline; print}')
echo
echo "Found ${#keys[@]} keys:"

i=0
for key in "${keys[@]}"; do
  ((i++))
  type_resp="$(redis_cmd TYPE "$key")"
  key_type="$(echo "$type_resp" | sed -n 's/^+//p')"
  echo
  echo "$i. Key: $key"
  echo "   Type: $key_type"

  case "$key_type" in
  string)
    val="$(redis_cmd GET "$key" | awk 'NR==2')"
    echo "   Value: $val"
    ;;
  list)
    len="$(redis_cmd LLEN "$key" | sed -n 's/^://p')"
    echo "   Length: $len"
    vals="$(redis_cmd LRANGE "$key" 0 -1 | awk '/^\$/ {getline; printf "%s ", $0}')"
    echo "   Values: [$vals]"
    ;;
  set)
    members="$(redis_cmd SMEMBERS "$key" | awk '/^\$/ {getline; printf "%s ", $0}')"
    echo "   Members: {$members}"
    ;;
  hash)
    pairs="$(redis_cmd HGETALL "$key")"
    echo "   Hash data:"
    echo "$pairs" | awk '
        /^\$/ {getline f; getline v; printf "     %s: %s\n", f,v}'
    ;;
  zset)
    zdata="$(redis_cmd ZRANGE "$key" 0 -1 WITHSCORES)"
    echo "   Sorted set data:"
    echo "$zdata" | awk '
        /^\$/ {getline m; getline; getline s; printf "     (%s, %s)\n", m,s}'
    ;;
  *)
    echo "   (unsupported type)"
    ;;
  esac
done
