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

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REGISTRY_TOOL="${SCRIPT_DIR}/instance-registry.py"
REGISTRY_PATH_DEFAULT="${SCRIPT_DIR}/runtime/registry/instances.json"

INSTANCE_ID=""
INSTANCE_SLUG=""
CONTAINER_NAME=""
REGISTRY_PATH="${REGISTRY_PATH:-$REGISTRY_PATH_DEFAULT}"
PURGE_DATA=0

usage() {
  cat <<'EOF'
Usage:
  ./remove-instance.sh [--instance-id <id> | --slug <slug> | --container-name <name>] [options]

Options:
  --instance-id <id>       Remove by instance id.
  --slug <slug>            Remove by instance slug.
  --container-name <name>  Remove by container name.
  --purge-data             Delete instance data directory after container removal.
  --registry <path>        Registry JSON path.
  --help                   Show this help.
EOF
}

log() {
  printf '[remove-instance] %s\n' "$*"
}

die() {
  printf '[remove-instance] %s\n' "$*" >&2
  exit 1
}

purge_instance_root() {
  local instance_root="$1"
  local image_name="$2"

  [[ -d "$instance_root" ]] || return 0

  docker run --rm \
    -v "${instance_root}:/target" \
    --entrypoint /bin/sh \
    "$image_name" \
    -c 'rm -rf /target/* /target/.[!.]* /target/..?*' >/dev/null

  rmdir "$instance_root"
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --instance-id)
      INSTANCE_ID="${2:-}"
      shift 2
      ;;
    --slug)
      INSTANCE_SLUG="${2:-}"
      shift 2
      ;;
    --container-name)
      CONTAINER_NAME="${2:-}"
      shift 2
      ;;
    --registry)
      REGISTRY_PATH="${2:-}"
      shift 2
      ;;
    --purge-data)
      PURGE_DATA=1
      shift
      ;;
    --help|-h)
      usage
      exit 0
      ;;
    *)
      die "unknown argument: $1"
      ;;
  esac
done

if [[ -z "$INSTANCE_ID$INSTANCE_SLUG$CONTAINER_NAME" ]]; then
  die "one of --instance-id, --slug or --container-name is required"
fi

REGISTRY_GET_ARGS=(--registry "$REGISTRY_PATH" get)
if [[ -n "$INSTANCE_ID" ]]; then
  REGISTRY_GET_ARGS+=(--instance-id "$INSTANCE_ID")
fi
if [[ -n "$INSTANCE_SLUG" ]]; then
  REGISTRY_GET_ARGS+=(--slug "$INSTANCE_SLUG")
fi
if [[ -n "$CONTAINER_NAME" ]]; then
  REGISTRY_GET_ARGS+=(--container-name "$CONTAINER_NAME")
fi

if ! RECORD_JSON="$("$REGISTRY_TOOL" "${REGISTRY_GET_ARGS[@]}" 2>/dev/null)"; then
  die "instance not found in registry"
fi

INSTANCE_ID="$(printf '%s' "$RECORD_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["instance_id"])')"
INSTANCE_SLUG="$(printf '%s' "$RECORD_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["instance_slug"])')"
CONTAINER_NAME="$(printf '%s' "$RECORD_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["container_name"])')"
INSTANCE_ROOT="$(printf '%s' "$RECORD_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["instance_root"])')"
IMAGE_NAME="$(printf '%s' "$RECORD_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["image_name"])')"

if docker container inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
  log "removing container ${CONTAINER_NAME}"
  docker rm -f "$CONTAINER_NAME" >/dev/null
else
  log "container ${CONTAINER_NAME} already absent"
fi

"$REGISTRY_TOOL" --registry "$REGISTRY_PATH" remove --instance-id "$INSTANCE_ID" >/dev/null

if [[ "$PURGE_DATA" -eq 1 ]]; then
  log "purging instance data ${INSTANCE_ROOT}"
  purge_instance_root "$INSTANCE_ROOT" "$IMAGE_NAME"
fi

cat <<EOF
instance_id=${INSTANCE_ID}
instance_slug=${INSTANCE_SLUG}
container_name=${CONTAINER_NAME}
instance_root=${INSTANCE_ROOT}
purged_data=${PURGE_DATA}
EOF
