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

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
STACK_ENV="${STACK_ENV:-$ROOT_DIR/stack.env}"
ENSURE_XMPP_SECRET_SCRIPT="$ROOT_DIR/utilities/prosody/ensure_xmpp_secret.sh"

podman_cmd() {
  if [[ "$(id -u)" -eq 0 ]] && id code >/dev/null 2>&1; then
    local quoted=()
    local arg
    for arg in "$@"; do
      quoted+=("$(printf '%q' "$arg")")
    done
    su -s /bin/sh code -c "podman ${quoted[*]}"
    return
  fi
  podman "$@"
}

if [[ -f "$STACK_ENV" ]]; then
  set -a
  . "$STACK_ENV"
  set +a
fi

if [[ -x "$ENSURE_XMPP_SECRET_SCRIPT" ]]; then
  XMPP_SECRET="$("$ENSURE_XMPP_SECRET_SCRIPT" "$STACK_ENV")"
  export XMPP_SECRET
fi

STACK_ID="${GIA_STACK_ID:-${STACK_ID:-}}"
STACK_ID="$(echo "$STACK_ID" | tr -cs 'a-zA-Z0-9._-' '-' | sed 's/^-*//; s/-*$//')"

name_with_stack() {
  local base="$1"
  if [[ -n "$STACK_ID" ]]; then
    echo "${base}_${STACK_ID}"
  else
    echo "$base"
  fi
}

POD_NAME="$(name_with_stack "gia")"
PROSODY_CONTAINER="$(name_with_stack "prosody_gia")"

resolve_runtime_names() {
  local candidates
  candidates="$(
    podman_cmd pod ps --format '{{.Name}}' 2>/dev/null \
      | grep -E '^((pod_)?gia)($|_[a-zA-Z0-9._-]+$)' || true
  )"
  local expected=()
  if [[ -n "$STACK_ID" ]]; then
    expected+=("gia_${STACK_ID}" "pod_gia_${STACK_ID}")
  else
    expected+=("gia" "pod_gia")
  fi
  local name
  for name in "${expected[@]}"; do
    if printf '%s\n' "$candidates" | grep -qx "$name"; then
      POD_NAME="$name"
      break
    fi
  done

  if [[ "$POD_NAME" != "gia" ]] && [[ "$POD_NAME" != "pod_gia" ]] && ! podman_cmd pod exists "$POD_NAME" >/dev/null 2>&1; then
    POD_NAME="$(name_with_stack "gia")"
  fi

  if podman_cmd pod exists "$POD_NAME" >/dev/null 2>&1; then
    if [[ "$POD_NAME" == pod_gia* ]]; then
      local suffix="${POD_NAME#pod_gia}"
      suffix="${suffix#_}"
      if [[ -n "$suffix" ]]; then
        PROSODY_CONTAINER="prosody_gia_${suffix}"
      else
        PROSODY_CONTAINER="prosody_gia"
      fi
    elif [[ "$POD_NAME" == gia_* ]]; then
      local suffix="${POD_NAME#gia_}"
      PROSODY_CONTAINER="prosody_gia_${suffix}"
    else
      PROSODY_CONTAINER="prosody_gia"
    fi
    return
  fi

  # Fallback: if only one gia-like pod exists, use it.
  local count
  count="$(printf '%s\n' "$candidates" | sed '/^$/d' | wc -l | tr -d ' ')"
  if [[ "$count" != "1" ]]; then
    return
  fi

  local detected
  detected="$(printf '%s\n' "$candidates" | sed '/^$/d' | head -n1)"
  [[ -z "$detected" ]] && return

  POD_NAME="$detected"
  if [[ "$POD_NAME" == pod_gia_* ]]; then
    local suffix="${POD_NAME#pod_gia_}"
    PROSODY_CONTAINER="prosody_gia_${suffix}"
  elif [[ "$POD_NAME" == pod_gia ]]; then
    PROSODY_CONTAINER="prosody_gia"
  elif [[ "$POD_NAME" == gia_* ]]; then
    local suffix="${POD_NAME#gia_}"
    PROSODY_CONTAINER="prosody_gia_${suffix}"
  else
    PROSODY_CONTAINER="prosody_gia"
  fi
  echo "Info: auto-detected pod '$POD_NAME' and Prosody container '$PROSODY_CONTAINER'." >&2
}

PROSODY_CONFIG_FILE="${QUADLET_PROSODY_CONFIG_FILE:-$ROOT_DIR/utilities/prosody/prosody.cfg.lua}"
PROSODY_CERTS_DIR="${QUADLET_PROSODY_CERTS_DIR:-$ROOT_DIR/.podman/gia_prosody_certs}"
PROSODY_DATA_DIR="${QUADLET_PROSODY_DATA_DIR:-$ROOT_DIR/.podman/gia_prosody_data}"
PROSODY_LOGS_DIR="${QUADLET_PROSODY_LOGS_DIR:-$ROOT_DIR/.podman/gia_prosody_logs}"
PROSODY_IMAGE="${PROSODY_IMAGE:-docker.io/prosody/prosody:latest}"
if id code >/dev/null 2>&1; then
  PROSODY_RUN_USER_DEFAULT="$(id -u code):$(id -g code)"
else
  PROSODY_RUN_USER_DEFAULT="$(id -u):$(id -g)"
fi
PROSODY_RUN_USER="${PROSODY_RUN_USER:-$PROSODY_RUN_USER_DEFAULT}"

mkdir -p "$PROSODY_CERTS_DIR" "$PROSODY_DATA_DIR" "$PROSODY_LOGS_DIR"

up() {
  resolve_runtime_names
  local run_args=()
  local pod_state=""
  if podman_cmd pod exists "$POD_NAME"; then
    pod_state="$(podman_cmd pod inspect "$POD_NAME" --format '{{.State}}' 2>/dev/null || true)"
    if [[ -z "$pod_state" ]]; then
      pod_state="$(podman_cmd pod ps --format '{{.Name}} {{.Status}}' 2>/dev/null | awk -v pod="$POD_NAME" '$1==pod {print $2}')"
    fi
    if [[ "$pod_state" != "Running" && "$pod_state" != "Degraded" ]]; then
      podman_cmd pod start "$POD_NAME" >/dev/null 2>&1 || true
      pod_state="$(podman_cmd pod inspect "$POD_NAME" --format '{{.State}}' 2>/dev/null || true)"
      if [[ -z "$pod_state" ]]; then
        pod_state="$(podman_cmd pod ps --format '{{.Name}} {{.Status}}' 2>/dev/null | awk -v pod="$POD_NAME" '$1==pod {print $2}')"
      fi
    fi
    if [[ "$pod_state" == "Running" || "$pod_state" == "Degraded" ]]; then
      run_args+=(--pod "$POD_NAME")
    else
      echo "Warning: pod '$POD_NAME' state is '$pod_state'; starting $PROSODY_CONTAINER standalone with explicit ports." >&2
      run_args+=(-p 5222:5222 -p 5269:5269 -p 5280:5280 -p 8888:8888)
    fi
  else
    echo "Warning: pod '$POD_NAME' not found; starting $PROSODY_CONTAINER standalone with explicit ports." >&2
    run_args+=(-p 5222:5222 -p 5269:5269 -p 5280:5280 -p 8888:8888)
  fi
  podman_cmd run -d \
    --replace \
    --name "$PROSODY_CONTAINER" \
    "${run_args[@]}" \
    --env-file "$STACK_ENV" \
    --user "$PROSODY_RUN_USER" \
    --entrypoint prosody \
    -v "$PROSODY_CONFIG_FILE:/etc/prosody/prosody.cfg.lua:ro" \
    -v "$PROSODY_CERTS_DIR:/etc/prosody/certs" \
    -v "$PROSODY_DATA_DIR:/var/lib/prosody" \
    -v "$PROSODY_LOGS_DIR:/var/log/prosody" \
    -v "$ROOT_DIR:/code" \
    "$PROSODY_IMAGE" \
    -F >/dev/null
  if [[ " ${run_args[*]} " == *" --pod "* ]]; then
    echo "Started $PROSODY_CONTAINER in pod $POD_NAME"
  else
    echo "Started $PROSODY_CONTAINER standalone (not attached to pod $POD_NAME)"
  fi
}

down() {
  resolve_runtime_names
  podman_cmd rm -f "$PROSODY_CONTAINER" >/dev/null 2>&1 || true
  echo "Stopped $PROSODY_CONTAINER"
}

status() {
  resolve_runtime_names
  podman_cmd ps --format "table {{.Names}}\t{{.Status}}" | grep -E "^$PROSODY_CONTAINER\b" || true
}

logs() {
  resolve_runtime_names
  podman_cmd logs -f "$PROSODY_CONTAINER"
}

case "${1:-}" in
  up)
    up
    ;;
  down)
    down
    ;;
  restart)
    down
    up
    ;;
  status)
    status
    ;;
  logs)
    logs
    ;;
  *)
    echo "Usage: $0 {up|down|restart|status|logs}" >&2
    exit 2
    ;;
esac
