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

CONTAINER_NAME="${WECOM_AIBOT_CONTAINER_NAME:-zhct-wecom-aibot}"
DEPLOY_SERVICE="${WECOM_AIBOT_DEPLOY_SERVICE:-zhct-wecom-aibot-deploy.service}"
HEALTH_TIMEOUT="${WECOM_AIBOT_WATCHDOG_HEALTH_TIMEOUT:-90}"
LOCK_FILE="${WECOM_AIBOT_WATCHDOG_LOCK_FILE:-/run/lock/zhct-wecom-aibot-watchdog.lock}"

log() {
  printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S %z')" "$*"
}

container_state() {
  docker inspect --format '{{.State.Status}}' "$CONTAINER_NAME" 2>/dev/null || true
}

container_health() {
  docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' \
    "$CONTAINER_NAME" 2>/dev/null || true
}

wait_for_health() {
  local deadline=$((SECONDS + HEALTH_TIMEOUT))
  local health

  while (( SECONDS < deadline )); do
    health="$(container_health)"
    [[ "$health" == "healthy" ]] && return 0
    [[ "$health" == "exited" || "$health" == "dead" ]] && return 1
    sleep 3
  done
  return 1
}

command -v docker >/dev/null
command -v flock >/dev/null

exec 9>"$LOCK_FILE"
flock -n 9 || exit 0

state="$(container_state)"
health="$(container_health)"
if [[ "$state" == "running" && "$health" != "unhealthy" ]]; then
  exit 0
fi

if [[ -z "$state" ]]; then
  log "container is missing; starting deployment service"
  systemctl start "$DEPLOY_SERVICE"
  exit 0
fi

if [[ "$state" == "running" ]]; then
  log "container is unhealthy; restarting it"
  docker restart "$CONTAINER_NAME" >/dev/null
else
  log "container state is $state; starting it"
  docker start "$CONTAINER_NAME" >/dev/null
fi

if wait_for_health; then
  log "container recovered and is healthy"
  exit 0
fi

log "direct recovery failed; starting deployment service"
systemctl restart "$DEPLOY_SERVICE"
