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

DOCKER_BIN="${DOCKER_BIN:-/usr/local/bin/docker}"
if [[ ! -x "${DOCKER_BIN}" ]]; then
  DOCKER_BIN="$(command -v docker)"
fi

fetch_with_retry() {
  local url="$1"
  shift
  local output=""
  local attempt

  for attempt in 1 2 3 4 5 6 7 8 9 10; do
    if output="$(curl -k -fsS --compressed "$@" "$url")"; then
      printf '%s' "$output"
      return 0
    fi
    echo "not-ready url=${url} attempt=${attempt}" >&2
    sleep 10
  done

  return 1
}

echo "== containers =="
"${DOCKER_BIN}" ps --filter 'name=nodedc-platform' --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'

echo "== launcher storage check =="
"${DOCKER_BIN}" exec nodedc-platform-launcher-1 sh -lc \
  'touch /app/server/storage/.write-test /app/server/storage/uploads/.write-test && rm /app/server/storage/.write-test /app/server/storage/uploads/.write-test && echo storage-ok'

echo "== launcher -> authentik api check =="
"${DOCKER_BIN}" exec nodedc-platform-launcher-1 sh -lc '
  echo "$NODEDC_AUTHENTIK_BASE_URL"
  getent hosts nodedc-platform-authentik-server
  for attempt in 1 2 3 4 5 6 7 8 9 10; do
    if wget -qSO- \
      --header "Authorization: Bearer $NODEDC_AUTHENTIK_SERVICE_TOKEN" \
      "$NODEDC_AUTHENTIK_BASE_URL/api/v3/core/groups/?search=nodedc_admin" \
      >/tmp/authentik-api-check.json \
      2>/tmp/authentik-api-check.headers; then
      head -n 25 /tmp/authentik-api-check.headers
      exit 0
    fi
    head -n 25 /tmp/authentik-api-check.headers || true
    echo "authentik-api-not-ready attempt=$attempt"
    sleep 10
  done
  exit 1
'

echo "== notification core health check =="
"${DOCKER_BIN}" exec nodedc-platform-notification-core-1 sh -lc \
  'wget -qSO- http://127.0.0.1:5185/healthz 2>&1 | head -n 25'

echo "== ai workspace hub health check =="
"${DOCKER_BIN}" exec nodedc-platform-ai-workspace-hub-1 sh -lc \
  'node -e '"'"'fetch("http://127.0.0.1:18081/healthz").then(async (response) => { console.log(await response.text()); process.exit(response.ok ? 0 : 1); }).catch((error) => { console.error(error); process.exit(1); })'"'"''

echo "== ai workspace assistant health check =="
"${DOCKER_BIN}" exec nodedc-platform-ai-workspace-assistant-1 sh -lc \
  'node -e '"'"'fetch("http://127.0.0.1:18082/healthz").then(async (response) => { console.log(await response.text()); process.exit(response.ok ? 0 : 1); }).catch((error) => { console.error(error); process.exit(1); })'"'"''

echo "== ontology core health check =="
"${DOCKER_BIN}" exec nodedc-platform-ontology-core-1 sh -lc \
  'node -e '"'"'fetch("http://127.0.0.1:18104/healthz").then(async (response) => { console.log(await response.text()); process.exit(response.ok ? 0 : 1); }).catch((error) => { console.error(error); process.exit(1); })'"'"''

echo "== frozen legacy gelios gateway health check =="
"${DOCKER_BIN}" exec nodedc-platform-gelios-gateway-1 sh -lc \
  'node -e '"'"'fetch("http://127.0.0.1:18105/healthz").then(async (response) => { console.log(await response.text()); process.exit(response.ok ? 0 : 1); }).catch((error) => { console.error(error); process.exit(1); })'"'"''

echo "== ai workspace assistant hub target check =="
"${DOCKER_BIN}" exec nodedc-platform-ai-workspace-assistant-1 sh -lc \
  'test "$AI_WORKSPACE_HUB_PUBLIC_URL" = "wss://ai-hub.nodedc.ru/api/ai-workspace/hub" && test -z "$AI_WORKSPACE_HUB_FALLBACK_URLS" && echo ai-workspace-prod-hub-target-ok'

echo "== ai workspace assistant Ops entitlement adapter check =="
"${DOCKER_BIN}" exec nodedc-platform-ai-workspace-assistant-1 sh -lc \
  'test "$AI_WORKSPACE_OPS_ENTITLEMENT_URL" = "http://172.22.0.222:18190/api/internal/v1/ai-workspace/entitlements" && test -n "$AI_WORKSPACE_OPS_ENTITLEMENT_TOKEN" && echo ai-workspace-ops-entitlement-env-ok'

echo "== BIM viewer auth/session check =="
bim_session="$(fetch_with_retry http://127.0.0.1:18100/api/auth/session)"
printf '%s' "$bim_session" | grep -aE '"authRequired":true|"loginUrl"'

echo "== BIM viewer public redirect check =="
bim_public_status="$(
  curl -k -sS -o /dev/null -w '%{http_code}' https://bim.nodedc.tech/
)"
if [[ "$bim_public_status" != "302" ]]; then
  echo "public BIM root did not redirect to Launcher auth: status=${bim_public_status}"
  exit 1
fi
echo "bim-public-auth-redirect-ok"

echo "== auth flow check =="
auth_flow="$(fetch_with_retry https://id.nodedc.ru/if/flow/default-authentication-flow/)"
printf '%s' "$auth_flow" \
  | grep -aE 'syncFormFieldsBeforeSubmit|branding_custom_css = ""|Запросить доступ'

echo "== public admin closed check =="
id_admin_status="$(
  curl -k -sS -o /dev/null -w '%{http_code}' https://id.nodedc.ru/if/admin/
)"
if [[ "$id_admin_status" != "404" ]]; then
  echo "public id admin is not closed: status=${id_admin_status}"
  exit 1
fi
echo "public-id-admin-closed-ok"

echo "== technical admin css check =="
auth_admin_page="$(
  fetch_with_retry http://127.0.0.1:18080/if/admin/ -H 'Host: auth-admin.nas.nodedc'
)"
printf '%s' "$auth_admin_page" \
  | grep -aE '<style data-id="brand-css"></style>|authentikBrand.branding_custom_css = ""'

auth_admin_flow="$(
  fetch_with_retry http://127.0.0.1:18080/if/flow/default-authentication-flow/ -H 'Host: auth-admin.nas.nodedc'
)"
if printf '%s' "$auth_admin_flow" | grep -aq '<style data-id="nodedc-auth-login-css">'; then
  echo "admin host still has NODE.DC auth CSS"
  exit 1
fi
echo "auth-admin-css-ok"

echo "== technical admin ip fallback check =="
ip_admin_page="$(
  fetch_with_retry http://172.22.0.222:18080/if/admin/
)"
printf '%s' "$ip_admin_page" \
  | grep -aE '<style data-id="brand-css"></style>|authentikBrand.branding_custom_css = ""'

echo "== launcher bundle check =="
launcher_html="$(fetch_with_retry https://hub.nodedc.ru/ -H 'Accept: text/html')"
launcher_asset="$(
  printf '%s' "$launcher_html" \
    | grep -aoE 'index-[A-Za-z0-9_-]+\.js' \
    | head -n 1
)"
test -n "$launcher_asset"
echo "launcher_asset=${launcher_asset}"
if fetch_with_retry "https://hub.nodedc.ru/assets/${launcher_asset}" \
  | grep -aq 'Заявка ожидает подтверждения'; then
  echo "old pending gate still present"
  exit 1
fi
echo "launcher-pending-gate-ok"

echo "runtime-verify-ok"
