#!/bin/sh
set -eu

DEPLOY_PATH="${DEPLOY_PATH:-/home/projekte_bao/nexus}"
ENV_TMPFILE_TEMPLATE="${ENV_TMPFILE:-/tmp/nexus-deploy-env}"
ENV_TMPFILE=""
BASE_URL="${BASE_URL:-https://nexus.noveria.net}"

cleanup() {
  if [ -n "$ENV_TMPFILE" ] && [ -f "$ENV_TMPFILE" ]; then
    shred -u "$ENV_TMPFILE" 2>/dev/null || rm -f "$ENV_TMPFILE"
  fi
}
trap cleanup EXIT INT TERM

require_env() {
  name="$1"
  eval "value=\${$name:-}"
  if [ -z "$value" ]; then
    echo "Missing required environment variable: $name" >&2
    exit 1
  fi
}

require_env ENV_POSTGRES_PASSWORD
require_env ENV_JWT_KEY

secure_tmpfile() {
  template="$1"
  dir="$(dirname "$template")"
  base="$(basename "$template")"
  mkdir -p "$dir"
  mktemp "$dir/$base.XXXXXX"
}

ENV_TMPFILE="$(secure_tmpfile "$ENV_TMPFILE_TEMPLATE")"
chmod 600 "$ENV_TMPFILE"

if [ ! -f VERSION ]; then
  echo "VERSION file not found" >&2
  exit 1
fi

VERSION="$(tr -d '[:space:]' < VERSION)"
if ! echo "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
  echo "Invalid VERSION value: $VERSION" >&2
  exit 1
fi

GIT_SHA="$(git rev-parse HEAD 2>/dev/null || echo unknown)"
GIT_REF="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
echo "Deploying Nexus v$VERSION from $GIT_REF"

umask 077
cat > "$ENV_TMPFILE" <<EOF_ENV
POSTGRES_DB=nexus
POSTGRES_USER=nexus
POSTGRES_PASSWORD=${ENV_POSTGRES_PASSWORD}
JWT_KEY=${ENV_JWT_KEY}
JWT_ISSUER=nexus
JWT_AUDIENCE=nexus-web
BOOTSTRAP_OWNER_EMAIL=vmbao62@hotmail.de
BOOTSTRAP_OWNER_PASSWORD=${ENV_BOOTSTRAP_OWNER_PASSWORD:-}
OPENCLAW_BASE_URL=http://openclaw-gateway:18789
OPENCLAW_REQUIRED_VERSION=2026.7.1
OPENCLAW_GATEWAY_TOKEN=${ENV_OPENCLAW_TOKEN:-}
OPENCLAW_GATEWAY_PASSWORD=
OPENCLAW_EXTERNAL_CLIENT_ID_SUPPORTED=false
OPENCLAW_ALLOW_COMMAND_CRON=false
NEXUS_VERSION=${VERSION}
NEXUS_GIT_SHA=${GIT_SHA}
EOF_ENV

echo "Syncing source to deploy path: $DEPLOY_PATH"
git archive --format=tar HEAD | docker run --rm -i \
  -v "$DEPLOY_PATH:/dest" \
  alpine:3.20 \
  sh -c '
    set -eu
    dest_owner="$(stat -c "%u:%g" /dest)"
    mkdir -p /src-snapshot
    tar -xf - -C /src-snapshot

    is_protected_path() {
      case "$1" in
        ./.git|./.git/*|./.env|./.env.*|./data|./data/*|./logs|./logs/*|./backups|./backups/*|./tmp|./tmp/*|./uploads|./uploads/*|./storage|./storage/*)
          return 0
          ;;
        *)
          return 1
          ;;
      esac
    }

    cd /dest
    find . -mindepth 1 -maxdepth 1 | while IFS= read -r path; do
      if ! is_protected_path "$path"; then
        rm -rf "$path"
      fi
    done

    cd /src-snapshot
    find . -mindepth 1 -maxdepth 1 | while IFS= read -r path; do
      if ! is_protected_path "$path"; then
        cp -a "$path" /dest/
      fi
    done

    chown -R "$dest_owner" /dest
  '

echo "Building and starting Docker compose stack"
docker run --rm \
  -v "$DEPLOY_PATH:/workspace/nexus" \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -w /workspace/nexus \
  -i \
  docker:cli \
  sh -c 'set -eu
    umask 077
    cat > /tmp/nexus-deploy-env
    trap '\''rm -f /tmp/nexus-deploy-env'\'' EXIT INT TERM
    docker compose --env-file /tmp/nexus-deploy-env build
    docker compose --env-file /tmp/nexus-deploy-env up -d --force-recreate --remove-orphans --wait
    docker compose --env-file /tmp/nexus-deploy-env ps
  ' < "$ENV_TMPFILE"

echo "Checking container readiness"
retry=0
while [ "$retry" -lt 6 ]; do
  retry=$((retry + 1))
  if docker exec nexus-api-1 curl -fs --max-time 5 http://localhost:8080/health/ready >/dev/null; then
    echo "API container is ready"
    break
  fi
  if [ "$retry" -eq 6 ]; then
    echo "API container readiness failed" >&2
    exit 1
  fi
  sleep "$retry"
done

echo "Verifying image provenance"
for container in nexus-api-1 nexus-web-1; do
  revision="$(docker inspect --format '{{ index .Config.Labels "org.opencontainers.image.revision" }}' "$container")"
  version="$(docker inspect --format '{{ index .Config.Labels "org.opencontainers.image.version" }}' "$container")"
  if [ "$revision" != "$GIT_SHA" ]; then
    echo "Image revision mismatch for $container: expected $GIT_SHA, got $revision" >&2
    exit 1
  fi
  if [ "$version" != "$VERSION" ]; then
    echo "Image version mismatch for $container: expected $VERSION, got $version" >&2
    exit 1
  fi
  echo "$container provenance verified: v$version $revision"
done

echo "Checking public readiness and dependency health"
readiness_is_healthy() {
  curl -fs --max-time 10 "$BASE_URL/health/ready" >/dev/null
}

runtime_is_healthy() {
  health_body="$(curl -fs --max-time 10 "$BASE_URL/health")" || return 1
  printf '%s' "$health_body" |
    grep -Eq '^[[:space:]]*\{[[:space:]]*"status"[[:space:]]*:[[:space:]]*"Healthy"'
}

retry=0
while [ "$retry" -lt 6 ]; do
  retry=$((retry + 1))
  if readiness_is_healthy && runtime_is_healthy; then
    echo "Readiness and full dependency health passed"
    break
  fi
  if [ "$retry" -eq 6 ]; then
    echo "Health check failed" >&2
    exit 1
  fi
  sleep "$retry"
done

pass=0
fail=0
check() {
  path="$1"
  expected="$2"
  label="$3"
  code="$(curl -sS -o /dev/null -w '%{http_code}' --max-time 10 "$BASE_URL$path")"
  printf '%-28s HTTP %s\n' "$label" "$code"
  if [ "$code" = "$expected" ]; then
    pass=$((pass + 1))
  else
    fail=$((fail + 1))
  fi
}

check_health() {
  if readiness_is_healthy && runtime_is_healthy; then
    printf '%-28s HTTP 200 (Ready + Healthy)\n' "Health"
    pass=$((pass + 1))
  else
    printf '%-28s not healthy\n' "Health"
    fail=$((fail + 1))
  fi
}

check_post() {
  path="$1"
  expected="$2"
  label="$3"
  code="$(curl -sS -o /dev/null -w '%{http_code}' --max-time 10 -X POST -H 'Content-Type: application/json' --data '{}' "$BASE_URL$path")"
  printf '%-28s HTTP %s\n' "$label" "$code"
  if [ "$code" = "$expected" ]; then
    pass=$((pass + 1))
  else
    fail=$((fail + 1))
  fi
}

check "/dashboard" "200" "Dashboard"
check_health
check "/api/v1/operations/snapshot" "401" "Operations auth"
check_post "/api/v1/chat" "401" "Chat auth"

if [ "$fail" -ne 0 ]; then
  echo "Smoke test failed: $fail failed, $pass passed" >&2
  exit 1
fi

echo "Nexus v$VERSION deployed and verified"
