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

if [[ ${EUID} -ne 0 ]]; then
  printf '%s\n' "bootstrap must run as root" >&2
  exit 1
fi

SOURCE_DIR=${1:-}
if [[ -z "$SOURCE_DIR" || ! -d "$SOURCE_DIR" ]]; then
  printf '%s\n' "usage: bootstrap.sh <uploaded-prod-directory>" >&2
  exit 1
fi

export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y ca-certificates certbot curl jq nginx openssl python3-certbot-dns-cloudflare restic rsync tar gzip ufw fail2ban docker.io docker-compose-v2 nodejs npm
systemctl enable --now docker nginx fail2ban

if ! id harbor >/dev/null 2>&1; then
  useradd --system --home /var/lib/harbor --shell /usr/sbin/nologin harbor
fi

install -d -m 0755 /opt/harbor /opt/harbor/releases /opt/harbor/slots /opt/harbor/deploy
install -d -m 2770 -o daniel -g harbor /opt/harbor/incoming
install -d -m 0750 -o harbor -g harbor /var/lib/harbor
install -d -m 0700 /var/backups/harbor
install -d -m 0750 -o root -g harbor /etc/harbor

# threads-profile scrape script needs a real Chromium; keep the browser cache
# under the harbor user's home so releases (which only ship node_modules) can
# reuse it across blue/green swaps.
playwright_version=1.55.1
PLAYWRIGHT_HOST_PLATFORM_OVERRIDE=ubuntu24.04-x64 npx --yes "playwright@$playwright_version" install-deps chromium
runuser -u harbor -- env HOME=/var/lib/harbor PLAYWRIGHT_HOST_PLATFORM_OVERRIDE=ubuntu24.04-x64 npx --yes "playwright@$playwright_version" install chromium chromium-headless-shell
rsync -a --delete "$SOURCE_DIR/" /opt/harbor/deploy/
chown -R root:root /opt/harbor/deploy
chmod +x /opt/harbor/deploy/remote/*.sh /opt/harbor/deploy/backup/backup.sh /opt/harbor/deploy/backup/offsite-sync.sh /opt/harbor/deploy/monitoring/job-health-check.sh

install -m 0644 /opt/harbor/deploy/config/gateway.yaml /etc/harbor/gateway.yaml
install -m 0644 /opt/harbor/deploy/systemd/harbor-gateway@.service /etc/systemd/system/harbor-gateway@.service
install -m 0644 /opt/harbor/deploy/systemd/harbor-worker@.service /etc/systemd/system/harbor-worker@.service
install -m 0644 /opt/harbor/deploy/systemd/harbor-backup.service /etc/systemd/system/harbor-backup.service
install -m 0644 /opt/harbor/deploy/systemd/harbor-backup.timer /etc/systemd/system/harbor-backup.timer
install -m 0644 /opt/harbor/deploy/systemd/harbor-job-health.service /etc/systemd/system/harbor-job-health.service
install -m 0644 /opt/harbor/deploy/systemd/harbor-job-health.timer /etc/systemd/system/harbor-job-health.timer
install -m 0644 /opt/harbor/deploy/systemd/harbor-offsite-backup.service /etc/systemd/system/harbor-offsite-backup.service
install -m 0644 /opt/harbor/deploy/systemd/harbor-offsite-backup.timer /etc/systemd/system/harbor-offsite-backup.timer

if [[ ! -f /etc/harbor/harbor.env ]]; then
  mongo_password=$(openssl rand -hex 24)
  redis_password=$(openssl rand -hex 24)
  minio_password=$(openssl rand -hex 24)
  grafana_password=$(openssl rand -base64 24 | tr -d '/+=')
  cat > /etc/harbor/harbor.env <<EOF
PUBLIC_HOST=threads-tool.30cm.net
PUBLIC_WEB_BASE=https://threads-tool.30cm.net
PUBLIC_API_BASE=https://threads-tool.30cm.net
CORS_ALLOWED_ORIGINS=https://threads-tool.30cm.net
MONGO_ROOT_USER=haixun
MONGO_ROOT_PASSWORD=$mongo_password
MONGO_DATABASE=haixun
MONGO_PORT=27017
MONGO_URI=mongodb://haixun:$mongo_password@127.0.0.1:27017/?authSource=admin
MONGO_URL=mongodb://haixun:$mongo_password@127.0.0.1:27017/haixun?authSource=admin
REDIS_PASSWORD=$redis_password
REDIS_PORT=6379
HAIXUN_REDIS_ADDR=127.0.0.1:6379
HAIXUN_REDIS_PASSWORD=$redis_password
REDIS_NAMESPACE=haixun:prod:v1
AI_MODEL_CACHE_FINGERPRINT_SECRET=$(openssl rand -hex 32)
MEMBER_SETTINGS_ENCRYPTION_KEY_ID=v1
MEMBER_SETTINGS_ENCRYPTION_KEY=$(openssl rand -base64 32)
AUTH_ACCESS_SECRET=$(openssl rand -base64 48)
AUTH_REFRESH_SECRET=$(openssl rand -base64 48)
SCOUT_SESSION_SECRET=$(openssl rand -base64 48)
SCOUT_CRAWLER_ENDPOINT=
SCOUT_CRAWLER_TOKEN=
MINIO_ROOT_USER=haixun
MINIO_ROOT_PASSWORD=$minio_password
MINIO_SERVER_URL=https://threads-tool.30cm.net
MINIO_BROWSER_REDIRECT_URL=http://127.0.0.1:9001
MINIO_API_PORT=9000
MINIO_CONSOLE_PORT=9001
HAIXUN_STORAGE_S3_ENDPOINT=http://127.0.0.1:9000
HAIXUN_STORAGE_S3_REGION=us-east-1
HAIXUN_STORAGE_S3_BUCKET=haixun-assets
HAIXUN_STORAGE_S3_ACCESS_KEY=haixun
HAIXUN_STORAGE_S3_SECRET_KEY=$minio_password
HAIXUN_STORAGE_S3_USE_PATH_STYLE=true
HAIXUN_STORAGE_S3_PUBLIC_BASE_URL=https://threads-tool.30cm.net/haixun-assets
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=$grafana_password
GRAFANA_ROOT_URL=http://localhost:3000
GRAFANA_PORT=3000
PROMETHEUS_PORT=9090
PROMETHEUS_RETENTION=30d
LOKI_PORT=3100
ALLOY_PORT=12345
ALERTMANAGER_PORT=9093
NODE_EXPORTER_PORT=9100
CADVISOR_PORT=8080
BLACKBOX_EXPORTER_PORT=9115
STRIPE_ENABLED=false
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
STRIPE_STARTER_PRICE_ID=
STRIPE_PRO_PRICE_ID=
STRIPE_SUCCESS_URL="https://threads-tool.30cm.net/app/usage/checkout?result=success&checkout_id={CHECKOUT_ID}&plan={PLAN_ID}"
STRIPE_CANCEL_URL="https://threads-tool.30cm.net/app/usage/checkout?result=cancel&plan={PLAN_ID}"
STRIPE_PORTAL_RETURN_URL=https://threads-tool.30cm.net/app/usage/plans
PLATFORM_AI_KEY=
PLATFORM_XAI_KEY=
PLATFORM_OPENCODE_KEY=
PLATFORM_EXA_KEY=
THREADS_APP_ID=
THREADS_APP_SECRET=
MAIL_SENDER="Harbor Desk <noreply@code.30cm.net>"
MAIL_SMTP_HOST=
MAIL_SMTP_PORT=587
MAIL_SMTP_USER=
MAIL_SMTP_PASSWORD=
MAIL_DEV_EXPOSE_CODE=false
BACKUP_RETENTION_DAYS=14
MINIO_ENDPOINT=http://127.0.0.1:9000
MINIO_ACCESS_KEY=haixun
MINIO_SECRET_KEY=$minio_password
MINIO_BUCKET=haixun-assets
EOF
  chmod 0600 /etc/harbor/harbor.env
fi

cat > /etc/harbor/gateway-blue.env <<'EOF'
PORT=8888
EOF
cat > /etc/harbor/gateway-green.env <<'EOF'
PORT=8889
EOF
chmod 0644 /etc/harbor/gateway-blue.env /etc/harbor/gateway-green.env

active_slot=blue
[[ -f /etc/harbor/active-slot ]] && active_slot=$(cat /etc/harbor/active-slot)
active_port=8888
[[ "$active_slot" == green ]] && active_port=8889
printf 'server 127.0.0.1:%s;\n' "$active_port" > /etc/nginx/harbor-active-server.conf
if [[ -f /etc/letsencrypt/live/threads-tool.30cm.net/fullchain.pem ]]; then
  install -m 0644 /opt/harbor/deploy/nginx/harbor-tls.conf /etc/nginx/sites-available/harbor.conf
else
  install -m 0644 /opt/harbor/deploy/nginx/harbor-http.conf /etc/nginx/sites-available/harbor.conf
fi
ln -sfn /etc/nginx/sites-available/harbor.conf /etc/nginx/sites-enabled/harbor.conf
rm -f /etc/nginx/sites-enabled/default

cat > /etc/sudoers.d/harbor-deploy <<'EOF'
daniel ALL=(root) NOPASSWD: /opt/harbor/deploy/remote/activate-release.sh *
daniel ALL=(root) NOPASSWD: /opt/harbor/deploy/remote/rollback.sh
daniel ALL=(root) NOPASSWD: /opt/harbor/deploy/remote/status.sh
EOF
chmod 0440 /etc/sudoers.d/harbor-deploy
visudo -cf /etc/sudoers.d/harbor-deploy

systemctl daemon-reload
docker compose --env-file /etc/harbor/harbor.env -f /opt/harbor/deploy/compose/docker-compose.yml pull
docker compose --env-file /etc/harbor/harbor.env -f /opt/harbor/deploy/compose/docker-compose.yml up -d --wait --wait-timeout 180

ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
nginx -t
systemctl reload nginx
systemctl enable --now harbor-backup.timer
systemctl enable --now harbor-job-health.timer
# offsite-sync.sh no-ops until RESTIC_REPOSITORY/RESTIC_PASSWORD are set in
# harbor.env, so it's safe to always enable the timer.
systemctl enable --now harbor-offsite-backup.timer

printf '%s\n' "bootstrap complete"
printf '%s\n' "runtime secrets: /etc/harbor/harbor.env"
