#!/usr/bin/env bash
# AutoSeg Viewer: carrega SÓ os estudos demo no viewer já instalado.
# Não reinstala nada, não mexe no helm nem nos serviços.
#
#   bash demo.sh                  carrega o demo 1.3.0 inteiro (7 estudos), se ainda não foi
#   bash demo.sh 007              carrega SÓ o DEMO007 (lâmina H&E do VENTANA, 234 MB)
#   bash demo.sh [007] --forcar   envia de novo mesmo se já foi (pode duplicar na lista)
#
# O demo 1.3.0 tem 7 estudos: DEMO001-004 (CT + RTSTRUCT/RTPLAN/RTDOSE) e
# DEMO005-007 (lâminas H&E; a DEMO007 é a do VENTANA). Faz o mesmo que a etapa
# "Carregando estudos demo" do install-viewer.sh, mostrando cada passo.
set -u

DIR=${VIEWER_DIR:-/opt/autoseg-viewer}
PKG_IP=${PKG_IP:-186.249.192.104}
PORTA=${VIEWER_PORT:-443}
SAMPLES=https://pkg.rtmedical.ai/api/packages/apps/generic/viewer-samples/1.3.0
TUDO_SHA=de23ba0628ff4224bf0ac8065717fb8e70b7845c4d546b4ed5a83c9d284eb508

die() { echo; echo "ERRO: $*" >&2; exit 1; }
passo() { echo; echo "== $*"; }

FORCAR=0; SO007=0
for a in "$@"; do
  case $a in
    --forcar) FORCAR=1 ;;
    007|DEMO007|demo007) SO007=1 ;;
    *) sed -n '4,7p' "$0" | sed 's/^# //'; exit 1 ;;
  esac
done
if [ "$SO007" = 1 ]; then
  NOME="DEMO007 (lâmina H&E do VENTANA)"; TAM="234 MB"; QTD="1 estudo (DEMO007)"
  DEMO_URL=${DEMO_URL:-$SAMPLES/demo007.zip}
  DEMO_SHA=${DEMO_SHA:-08d6435cc62864f703a9529a52faa0058e8667adabaee1b1d2fda8fef6673c63}
else
  NOME="demo 1.3.0 completo"; TAM="526 MB"; QTD="os 7 estudos (DEMO001 a DEMO007)"
  DEMO_URL=${DEMO_URL:-$SAMPLES/demo.zip}
  DEMO_SHA=${DEMO_SHA:-$TUDO_SHA}
fi

[ "$(id -u)" = 0 ] || [ -n "${VIEWER_DIR:-}" ] || die "rode como root"

passo "1. configuração do viewer ($DIR/config.env)"
[ -r "$DIR/config.env" ] || die "não achei $DIR/config.env. O viewer foi instalado pelo install-viewer.sh?"
APP_USER=teste; APP_PASSWORD=teste; SERVER_IP=''; APP_DOMAIN=''; SSO_DOMAIN=''
# shellcheck disable=SC1091
. "$DIR/config.env"
APP=${APP_DOMAIN:-$SERVER_IP}
[ -n "$APP" ] || die "o endereço do viewer não está em $DIR/config.env"
if [[ $APP =~ ^[0-9.]+$ ]]; then SSO=$APP
elif [ -n "$SSO_DOMAIN" ]; then SSO=$SSO_DOMAIN
elif [ "${APP#viewer.}" != "$APP" ]; then SSO="sso.${APP#viewer.}"
else SSO="sso.$APP"; fi
CA=$DIR/tls/ca.crt
[ -s "$CA" ] || die "não achei o certificado do viewer em $CA"
echo "endereço: https://$APP   login: https://$SSO   usuário: $APP_USER"
# Fala com o viewer pela própria máquina (127.0.0.1), com o certificado dele.
v() { curl -fsS --cacert "$CA" --resolve "$APP:$PORTA:127.0.0.1" --resolve "$SSO:$PORTA:127.0.0.1" "$@"; }
APPU="https://$APP"; SSOU="https://$SSO"
[ "$PORTA" = 443 ] || { APPU="$APPU:$PORTA"; SSOU="$SSOU:$PORTA"; }

# O instalador marca o demo completo em demo-seed.sha256; o DEMO007 sozinho
# tem marcador próprio. O demo completo já inclui o DEMO007.
MARK=$DIR/demo-seed.sha256
[ "$SO007" = 0 ] || MARK=$DIR/demo007-seed.sha256
ja=''
[ "$(cat "$MARK" 2>/dev/null || true)" != "${DEMO_SHA,,}" ] || ja="$NOME"
if [ "$SO007" = 1 ] && [ "$(cat "$DIR/demo-seed.sha256" 2>/dev/null || true)" = "$TUDO_SHA" ]; then
  ja="demo 1.3.0 completo, que já inclui o DEMO007"
fi
if [ "$FORCAR" = 0 ] && [ -n "$ja" ]; then
  echo
  echo "JÁ CARREGADO neste viewer: $ja."
  echo "Deve aparecer na lista depois do login."
  o=''; [ "$SO007" = 0 ] || o='007 '
  echo "Para enviar de novo assim mesmo (pode duplicar na lista): bash demo.sh ${o}--forcar"
  exit 0
fi

passo "2. serviços do viewer"
if [ -z "${SEM_KUBECTL:-}" ] && command -v kubectl >/dev/null; then
  kubectl -n autoseg get pods 2>&1 | sed 's/^/   /'
  echo "esperando todos ficarem prontos (até 15 min)..."
  kubectl -n autoseg wait --for=condition=Available deployment --all --timeout=15m 2>&1 | sed 's/^/   /' \
    || die "os serviços não ficaram prontos. Veja: kubectl -n autoseg get pods"
else
  echo "(kubectl não disponível: pulando a checagem)"
fi

passo "3. baixando $NOME ($TAM)"
TMP=$(mktemp -d "$DIR/.demo.XXXXXX") || die "não consegui criar pasta temporária em $DIR"
chmod 700 "$TMP"; trap 'rm -rf -- "$TMP"' EXIT
DL=()
PKGH=${DEMO_URL#https://}; PKGH=${PKGH%%/*}; PKGH=${PKGH%%:*}
if [ "$PKGH" = pkg.rtmedical.ai ] && ! getent hosts "$PKGH" >/dev/null; then
  echo "o DNS desta máquina não resolve $PKGH: usando o IP $PKG_IP direto"
  DL=(--resolve "$PKGH:443:$PKG_IP")
fi
echo "GET $DEMO_URL"
ok=0
for t in 1 2 3 4 5 6; do
  if curl -fSL --http1.1 -C - --progress-bar "${DL[@]}" -o "$TMP/demo.zip" "$DEMO_URL"; then ok=1; break; fi
  echo "download interrompido (tentativa $t/6); continuando de onde parou"; sleep 5
done
[ "$ok" = 1 ] || die "não consegui baixar o demo. Teste: curl -sS -o /dev/null -w '%{http_code}\n' ${DL[*]} https://$PKGH"
echo "baixado: $(du -h "$TMP/demo.zip" | cut -f1)"

passo "4. conferindo o SHA-256"
printf '%s  %s\n' "${DEMO_SHA,,}" "$TMP/demo.zip" | sha256sum -c --quiet - || die "SHA-256 do demo não confere (download corrompido?)"
echo "ok: ${DEMO_SHA:0:16}..."

passo "5. login no viewer ($APP_USER)"
pronto=0
for ((i=0; i<60; i++)); do
  if v -o /dev/null "$SSOU/realms/autoseg/.well-known/openid-configuration" 2>/dev/null; then pronto=1; break; fi
  [ "$i" = 0 ] && echo "esperando o login (Keycloak) responder..."
  sleep 2
done
[ "$pronto" = 1 ] || die "o login do viewer não respondeu em 120 s. Veja: kubectl -n autoseg get pods"
TOKEN=$(v -X POST "$SSOU/realms/autoseg/protocol/openid-connect/token" \
  -d grant_type=password -d client_id=autoseg-desktop \
  --data-urlencode "username=$APP_USER" --data-urlencode "password=$APP_PASSWORD" \
  | sed -n 's/.*"access_token" *: *"\([^"]*\)".*/\1/p')
[ -n "$TOKEN" ] || die "o login recusou $APP_USER. A senha mudou? Confira APP_PASSWORD em $DIR/config.env"
echo "login ok"

passo "6. enviando o ZIP ao viewer (pode levar alguns minutos)"
if ! curl -fS --progress-bar --cacert "$CA" --resolve "$APP:$PORTA:127.0.0.1" \
     -H "Authorization: Bearer $TOKEN" -F "file=@$TMP/demo.zip;type=application/zip" \
     -o "$TMP/resp.json" "$APPU/api/upload/zip"; then
  die "o envio falhou. Resposta: $(head -c 300 "$TMP/resp.json" 2>/dev/null)"
fi
RESP=$(cat "$TMP/resp.json")
[[ $RESP == *'"status":"completed"'* ]] || die "o viewer não aceitou o ZIP: $(printf '%s' "$RESP" | head -c 300)"
mapfile -t UIDS < <(printf '%s' "$RESP" | grep -oE '"study_instance_uid":"[0-9.]+"' | cut -d '"' -f 4 | sort -u)
[ "${#UIDS[@]}" -ge 1 ] || die "o viewer aceitou o ZIP mas não devolveu nenhum estudo"
echo "aceito: ${#UIDS[@]} estudo(s)"
[[ $RESP != *'"skipped_unsupported":true'* ]] || echo "AVISO: o viewer ignorou séries que não suporta (lâminas SM exigem backend com WSI)"

passo "7. conferindo se cada estudo aparece no viewer"
falhou=0
for uid in "${UIDS[@]}"; do
  ok=0
  for ((i=0; i<60; i++)); do
    L=$(v -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
      --data "{\"query\":\"query { series(study_instance_uid: \\\"$uid\\\") { modality } rtObjects(study_instance_uid: \\\"$uid\\\") { modality } }\"}" \
      "$APPU/api/graphql" 2>/dev/null || true)
    if [[ $L == *'"modality":"CT"'* && $L == *'"modality":"RTSTRUCT"'* && $L == *'"modality":"RTPLAN"'* && $L == *'"modality":"RTDOSE"'* ]]; then
      ok="CT + RTSTRUCT + RTPLAN + RTDOSE"; break
    fi
    if [[ $L == *'"modality":"SM"'* && $L != *'"modality":"CT"'* ]]; then ok="lâmina (SM)"; break; fi
    sleep 2
  done
  if [ "$ok" = 0 ]; then echo "   FALTA  $uid (não completou em 120 s)"; falhou=1
  else echo "   ok     $uid  $ok"; fi
done

if [ "$falhou" = 1 ]; then
  echo
  echo "Algum estudo não ficou completo. Espere uns minutos e confira na lista; se faltar,"
  echo "rode de novo com --forcar"
  exit 1
fi
printf '%s\n' "${DEMO_SHA,,}" > "$MARK"; chmod 600 "$MARK"
echo
echo "PRONTO: $QTD carregado(s). Abra https://$APP e entre com $APP_USER."
