#!/usr/bin/env bash
# Configure or roll back the external, read-only docs-node Streamable HTTP endpoint.
# Run manually: ./scripts/configure-docs-node-remote.sh [--rollback]
set -euo pipefail

repo_root=/var/www/html/dev/mcp-servers
vhost_file=/etc/apache2/sites-available/dev-01-ssl.conf
unit_file=/etc/systemd/system/docs-node-remote.service
env_dir=/etc/docs-node
env_file=/etc/docs-node/remote.env
host_name=dev-01.sophiainformatica.it
public_ip=212.54.224.234
public_prefix=/docs-node/

if [[ ${1:-} == --rollback ]]; then
  latest_backup=$(ls -1t /etc/apache2/sites-available/dev-01-ssl.conf.docs-node-backup-* 2>/dev/null | head -n 1 || true)
  sudo systemctl disable --now docs-node-remote.service 2>/dev/null || true
  if [[ -n $latest_backup ]]; then
    sudo cp "$latest_backup" "$vhost_file"
  else
    echo "No Apache backup found; the vhost was not changed." >&2
  fi
  sudo rm -f "$unit_file" "$env_file"
  sudo systemctl daemon-reload
  sudo apache2ctl configtest
  sudo systemctl reload apache2
  echo "docs-node remote endpoint rolled back."
  exit 0
fi

if [[ $# -ne 0 ]]; then
  echo "Usage: $0 [--rollback]" >&2
  exit 2
fi

[[ -f $repo_root/docs-node/index.js ]] || { echo "docs-node not found at $repo_root" >&2; exit 1; }
[[ -f $vhost_file ]] || { echo "Apache virtual host not found: $vhost_file" >&2; exit 1; }
command -v node >/dev/null || { echo "node is required." >&2; exit 1; }
command -v openssl >/dev/null || { echo "openssl is required." >&2; exit 1; }

if sudo test -e "$unit_file"; then
  echo "Existing docs-node systemd unit found; inspect it or run $0 --rollback first." >&2
  exit 1
fi
if sudo test -e "$env_file"; then
  if ! sudo grep -q "^DOCS_NODE_HTTP_TOKEN=" "$env_file"; then
    echo "Existing token file is incomplete; inspect it or run $0 --rollback first." >&2
    exit 1
  fi
  reuse_existing_token=1
else
  reuse_existing_token=0
fi
if grep -Fq "docs-node remote MCP proxy" "$vhost_file"; then
  echo "Apache already contains a docs-node proxy block; refusing to duplicate it." >&2
  exit 1
fi

backup_file="${vhost_file}.docs-node-backup-$(date +%Y%m%dT%H%M%S)"
sudo cp "$vhost_file" "$backup_file"
sudo install -d -m 0750 "$env_dir"
if [[ $reuse_existing_token -eq 0 ]]; then
  sudo sh -c "umask 077; token=\$(openssl rand -hex 32); printf '%s\\n' 'DOCS_NODE_MODE=remote-server' 'DOCS_NODE_HTTP_PORT=8787' 'DOCS_NODE_DB_PATH=$repo_root/docs-node/docs.db' \"DOCS_NODE_HTTP_TOKEN=\$token\" > '$env_file'"
else
  echo "Reusing the token generated by the interrupted setup."
fi
sudo chown root:root "$env_file"
sudo chmod 0600 "$env_file"

sudo tee "$unit_file" >/dev/null <<UNIT
[Unit]
Description=docs-node remote Streamable HTTP endpoint
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=DCorona
Group=www-data
WorkingDirectory=$repo_root
EnvironmentFile=$env_file
ExecStart=/usr/bin/node $repo_root/docs-node/index.js
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=$repo_root/docs-node

[Install]
WantedBy=multi-user.target
UNIT

sudo perl -0pi -e 's{    # Pass\n}{    # docs-node remote MCP proxy: backend remains loopback-only.\n    ProxyPass        /docs-node/  http://127.0.0.1:8787/ retry=0 connectiontimeout=5 timeout=600\n    ProxyPassReverse /docs-node/  http://127.0.0.1:8787/\n\n    # Pass\n}' "$vhost_file"

if ! sudo apache2ctl configtest; then
  sudo cp "$backup_file" "$vhost_file"
  sudo rm -f "$unit_file" "$env_file"
  echo "Apache configuration invalid; the changes were reverted." >&2
  exit 1
fi

sudo systemctl daemon-reload
sudo systemctl enable --now docs-node-remote.service
sudo systemctl reload apache2

service_ready=0
for attempt in {1..30}; do
  if curl -fsS http://127.0.0.1:8787/health >/dev/null; then
    service_ready=1
    break
  fi
  sleep 1
done
if [[ $service_ready -ne 1 ]]; then
  echo "docs-node-remote did not become ready on 127.0.0.1:8787 within 30 seconds." >&2
  sudo systemctl --no-pager --full status docs-node-remote.service >&2 || true
  exit 1
fi
curl --resolve "$host_name:443:$public_ip" -fsS "https://$host_name${public_prefix}health" >/dev/null
local_status=$(curl -sS -o /dev/null -w "%{http_code}" http://127.0.0.1:8787/sync/shelves)
public_status=$(curl --resolve "$host_name:443:$public_ip" -sS -o /dev/null -w "%{http_code}" "https://$host_name${public_prefix}sync/shelves")
if [[ $local_status != 401 || $public_status != 401 ]]; then
  echo "Expected unauthenticated sync to return 401 (local=$local_status public=$public_status)." >&2
  exit 1
fi
sudo sh -c "set -a; . '$env_file'; set +a; curl -fsS -H \"Authorization: Bearer \$DOCS_NODE_HTTP_TOKEN\" http://127.0.0.1:8787/sync/shelves >/dev/null; curl --resolve '$host_name:443:$public_ip' -fsS -H \"Authorization: Bearer \$DOCS_NODE_HTTP_TOKEN\" 'https://$host_name${public_prefix}sync/shelves' >/dev/null"

sudo systemctl --no-pager --full status docs-node-remote.service
cat <<INFO

docs-node remote endpoint is ready.
MCP URL: https://$host_name${public_prefix}mcp
Health:  https://$host_name${public_prefix}health
The bearer token is stored only in $env_file (mode 0600) and is not printed.
Read it only on this host with: sudo sed -n "s/^DOCS_NODE_HTTP_TOKEN=//p" $env_file
Rollback: $0 --rollback
INFO
