#!/usr/bin/env bash
set -euo pipefail
ACTION="${1:-}"
NAME='learnitive-os-redis'
OWNER="${LEARNITIVE_DEPLOYMENT:-www.learnitive.com}"

exists() { /usr/bin/docker inspect "$NAME" >/dev/null 2>&1; }
owned() {
  [[ "$(/usr/bin/docker inspect --format '{{index .Config.Labels "learnitive.deployment"}}' "$NAME" 2>/dev/null || true)" == "$OWNER" ]]
}

case "$ACTION" in
  prepare)
    if exists; then
      owned || { echo "Refusing to remove non-staging Docker container named $NAME" >&2; exit 1; }
      /usr/bin/docker rm -f "$NAME" >/dev/null
    fi
    : "${LEARNITIVE_REDIS_IMAGE:?Redis image is required}"
    : "${LEARNITIVE_REDIS_PASSWORD:?Redis password is required}"
    : "${LEARNITIVE_REDIS_MAXMEMORY:?Redis maxmemory is required}"
    [[ "$LEARNITIVE_REDIS_PASSWORD" =~ ^[a-f0-9]{64}$ ]] || { echo 'Redis password must be 64 lowercase hexadecimal characters.' >&2; exit 1; }
    [[ "$LEARNITIVE_REDIS_MAXMEMORY" =~ ^[1-9][0-9]*(kb|mb|gb)$ ]] || { echo 'Redis maxmemory must use a positive kb/mb/gb value.' >&2; exit 1; }
    # Keep the Redis password out of the long-lived docker/redis process argv.
    # The short-lived preparation container receives it only via environment and
    # writes a mode-0600 config into the private Docker data volume.
    /usr/bin/docker run --rm --pull=never --user 0:0 \
      -e LEARNITIVE_REDIS_PASSWORD \
      -e LEARNITIVE_REDIS_MAXMEMORY \
      -v learnitive-os-redis-data:/data \
      "$LEARNITIVE_REDIS_IMAGE" sh -ec '
        umask 077
        cat > /data/learnitive.conf <<EOF
bind 0.0.0.0
port 6379
protected-mode yes
requirepass ${LEARNITIVE_REDIS_PASSWORD}
appendonly yes
appendfsync everysec
save ""
maxmemory ${LEARNITIVE_REDIS_MAXMEMORY}
maxmemory-policy noeviction
EOF
        chown redis:redis /data/learnitive.conf
        chmod 0600 /data/learnitive.conf
      '
    ;;
  stop)
    if exists; then
      owned || { echo "Refusing to stop non-staging Docker container named $NAME" >&2; exit 1; }
      /usr/bin/docker stop -t 10 "$NAME" >/dev/null
    fi
    ;;
  *)
    echo "Usage: $0 prepare|stop" >&2
    exit 2
    ;;
esac
