#!/usr/bin/env bash
#ddev-generated

## Description: Use a different key-value store for Redis
## Usage: redis-backend <image> [optimize]
## Example: ddev redis-backend redis-alpine optimize

# Keep in sync with the default image in docker-compose.redis.yaml
DEFAULT_REDIS_DOCKER_IMAGE="redis:8"

REDIS_DOCKER_IMAGE=${1:-}
REDIS_CONFIG=${2:-}

function show_help() {
  cat <<EOF
Usage: ddev redis-backend <image|alias> [optimize]

Choose from predefined aliases, or provide any Redis-compatible Docker image.
Note that not every Docker image can work right away, and you may need to override
the "command:" in the docker-compose.redis_extra.yaml file

Available aliases:
  redis            ${DEFAULT_REDIS_DOCKER_IMAGE}
  redis-alpine     ${DEFAULT_REDIS_DOCKER_IMAGE}-alpine
  valkey           valkey/valkey:9
  valkey-alpine    valkey/valkey:9-alpine

Custom backend:
  You can specify any Docker image, e.g.:
    ddev redis-backend redis:7

Optional:
  optimize         Apply additional Redis configuration with resource limits
  optimized        Same as optimize

Examples:
  ddev redis-backend redis-alpine optimize
  ddev redis-backend valkey
  ddev redis-backend redis:8.2-alpine
EOF
  exit 0
}

function optimize_config() {
  [[ "$REDIS_CONFIG" != "optimized" && "$REDIS_CONFIG" != "optimize" ]] && return
  ddev dotenv set .ddev/.env.redis --redis-optimized=true
}

function change_hostname() {
  [[ "${REDIS_HOSTNAME:-}" == "" ]] && return
  ddev dotenv set .ddev/.env.redis --redis-hostname="$REDIS_HOSTNAME"
}

function cleanup() {
  rm -f "$DDEV_APPROOT/.ddev/.env.redis"
  rm -rf "$DDEV_APPROOT/.ddev/redis/"
  rm -f "$DDEV_APPROOT/.ddev/docker-compose.redis.yaml" "$DDEV_APPROOT/.ddev/docker-compose.redis_extra.yaml"

  redis_volume="ddev-$(ddev status -j | docker run -i --rm ddev/ddev-utilities jq -r '.raw.name')_redis"
  if docker volume ls -q | grep -qw "$redis_volume"; then
    ddev stop
    docker volume rm "$redis_volume"
  fi
}

function check_docker_image() {
  echo "Pulling ${REDIS_DOCKER_IMAGE}..."
  if ! docker pull "$REDIS_DOCKER_IMAGE"; then
    echo >&2 "❌ Unable to pull ${REDIS_DOCKER_IMAGE}"
    exit 2
  fi
}

function use_docker_image() {
  [[ "$REDIS_DOCKER_IMAGE" != "$DEFAULT_REDIS_DOCKER_IMAGE" ]] && ddev dotenv set .ddev/.env.redis --redis-docker-image="$REDIS_DOCKER_IMAGE"
  # Reinstall the same add-on version that is installed now
  local repo version flags=()
  IFS='|' read -r repo version < <(ddev add-on list --installed -j 2>/dev/null | docker run -i --rm ddev/ddev-utilities jq -r '.raw[] | select(.Name=="redis") | "\(.Repository // "")|\(.Version // "")"' 2>/dev/null)
  case "$version" in
    # installed from a local directory
    "") ;;
    pr-*) flags=(--pr "${version#pr-}") ;;
    v[0-9]*) flags=(--version "$version") ;;
    # the default branch name, e.g. "main"
    *) flags=(--default-branch) ;;
  esac
  ddev add-on get "${repo:-ddev/ddev-redis}" "${flags[@]}"
}

# "ddev add-on get" overwrites this file while it is running, so keep the main flow
# in a block, which bash reads completely before running it
{
  case "$REDIS_DOCKER_IMAGE" in
    redis)
      REDIS_DOCKER_IMAGE="$DEFAULT_REDIS_DOCKER_IMAGE"
      ;;
    redis-alpine)
      REDIS_DOCKER_IMAGE="${DEFAULT_REDIS_DOCKER_IMAGE}-alpine"
      ;;
    valkey)
      REDIS_DOCKER_IMAGE="valkey/valkey:9"
      REDIS_HOSTNAME="valkey"
      ;;
    valkey-alpine)
      REDIS_DOCKER_IMAGE="valkey/valkey:9-alpine"
      REDIS_HOSTNAME="valkey"
      ;;
    ""|--help|-h)
      show_help
      ;;
    *)
      # Allow unknown image, nothing to override
      ;;
  esac

  check_docker_image
  cleanup
  optimize_config
  change_hostname
  use_docker_image

  echo
  echo "✅ Redis backend: $REDIS_DOCKER_IMAGE"
  if [[ "$REDIS_CONFIG" == "optimized" || "$REDIS_CONFIG" == "optimize" ]]; then
    echo "⚙️ Redis config: optimized"
  else
    echo "⚙️ Redis config: default"
  fi

  echo
  echo "📝 Commit the '.ddev' directory to version control"

  echo
  echo "🔄 Redis config available after 'ddev restart'"
  exit 0
}
