#!/usr/bin/env bash
# DPF cloud-init installer — GCP Compute Engine single-VM
#
# This file is a Terraform templatefile (infra/terraform/single-vm/gcp/main.tf).
# Variables in ${ } are Terraform inputs resolved before cloud-init runs.
# Bash variable references using curly braces are written as $${ } in the
# template source to avoid collision with Terraform's interpolation syntax.
#
# Mirrors infra/terraform/single-vm/aws/user-data/install.sh.
# The only GCP-specific difference is the metadata endpoint used to
# retrieve the external IP in the completion message.
#
# Rendered script runs as root under cloud-init on Ubuntu 24.04 LTS.
# All output is tee'd to /var/log/dpf-install.log.
#
# Track progress after terraform apply:
#   gcloud compute ssh ubuntu@<instance-name> \
#     --project=<project> --zone=<zone> --tunnel-through-iap \
#     --command='tail -f /var/log/dpf-install.log'

set -euo pipefail

exec > >(tee -a /var/log/dpf-install.log) 2>&1

DPF_DIR="/opt/dpf"

echo ""
echo "============================================================"
echo "  DPF cloud-init starting at $(date -u)"
echo "  Repo:   ${dpf_repo_url}"
echo "  Branch: ${dpf_branch}"
echo "============================================================"

# ── 1. System packages ────────────────────────────────────────────────────────
echo ""
echo "-> [1/7] Installing system packages"

export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y -qq \
  curl git ca-certificates gnupg lsb-release apt-transport-https \
  build-essential openssl

echo "  [OK] System packages installed"

# ── 2. Docker Engine (official Docker apt repository) ────────────────────────
echo ""
echo "-> [2/7] Installing Docker Engine"

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
   https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) stable" \
  | tee /etc/apt/sources.list.d/docker.list > /dev/null

apt-get update -qq
apt-get install -y -qq \
  docker-ce docker-ce-cli containerd.io docker-compose-plugin

systemctl enable --now docker
docker info > /dev/null

echo "  [OK] Docker Engine $(docker --version)"

# ── 3. Node.js 24 (NodeSource) ───────────────────────────────────────────────
echo ""
echo "-> [3/7] Installing Node.js 24"

curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
apt-get install -y -qq nodejs

echo "  [OK] Node.js $(node -v)"

# ── 4. pnpm ───────────────────────────────────────────────────────────────────
echo ""
echo "-> [4/7] Installing pnpm"

npm install -g pnpm@10.33.2
echo "  [OK] pnpm $(pnpm -v)"

# ── 5. Clone DPF repository ───────────────────────────────────────────────────
echo ""
echo "-> [5/7] Cloning DPF repository"

if [ -d "$DPF_DIR/.git" ]; then
  echo "  Existing clone found — updating to origin/${dpf_branch}"
  git -C "$DPF_DIR" remote set-url origin "${dpf_repo_url}"
  git -C "$DPF_DIR" fetch origin "${dpf_branch}"
  git -C "$DPF_DIR" checkout "${dpf_branch}"
  git -C "$DPF_DIR" reset --hard "origin/${dpf_branch}"
else
  git clone --branch "${dpf_branch}" --depth 1 "${dpf_repo_url}" "$DPF_DIR"
fi

echo "  [OK] Repository at $DPF_DIR ($(git -C "$DPF_DIR" rev-parse --short HEAD))"

# ── 6. Write .env before the installer runs ───────────────────────────────────
echo ""
echo "-> [6/7] Writing .env with Terraform-supplied configuration"

AUTH_SECRET=$(openssl rand -base64 32)
ENC_KEY=$(openssl rand -hex 32)
ADMIN_PASS=$(printf '%s' '${dpf_admin_password_b64}' | base64 --decode)

cat > "$DPF_DIR/.env" << ENVEOF
# Generated by DPF cloud-init (infra/terraform/single-vm/gcp)
POSTGRES_USER=dpf
POSTGRES_PASSWORD=dpf_dev
DATABASE_URL=postgresql://dpf:dpf_dev@postgres:5432/dpf
NEO4J_AUTH=neo4j/dpf_dev_password
AUTH_SECRET=$AUTH_SECRET
CREDENTIAL_ENCRYPTION_KEY=$ENC_KEY
DPF_HOST_INSTALL_PATH=$DPF_DIR
DPF_BACKUPS_HOST_PATH=$DPF_DIR-backups
GF_ADMIN_USER=admin
GF_ADMIN_PASSWORD=dpf_monitor
DPF_LLM_PROVIDER=external
LLM_BASE_URL=${llm_base_url}
LLM_MODEL=${llm_model}
EMBEDDING_MODEL=${embedding_model}
BROWSER_USE_MODEL=
DPF_MODEL_PULL_MODE=auto
GHCR_OWNER=opendigitalproductfactory
DPF_IMAGE_TAG=latest
MCP_INSECURE_INTERNAL_HOSTS=
DPF_AUTHORITY_URL=
DPF_BOOTSTRAP_TOKEN=
DPF_EDGE_NODE_NAME=
DPF_INSTALL_MODE=container-vm
ENVEOF

printf 'ADMIN_PASSWORD=%s\n' "$ADMIN_PASS" >> "$DPF_DIR/.env"
printf 'HIVE_CONTRIBUTION_TOKEN=\n' >> "$DPF_DIR/.env"

echo "  [OK] .env written"

# ── 7. Run the DPF installer ──────────────────────────────────────────────────
echo ""
echo "-> [7/7] Running DPF installer (this takes 5-10 minutes)"
echo "   --headless  : no interactive prompts"
echo "   --release   : use pre-built GHCR images"
echo "   --no-autostart : Docker restart policies handle reboot on GCP VMs"
echo ""

cd "$DPF_DIR"
export DPF_HEADLESS=1
bash install-dpf.sh --headless --release --no-autostart

# ── Done ──────────────────────────────────────────────────────────────────────
# GCP metadata endpoint differs from AWS (v1beta1, no IMDSv2 token required).
PUBLIC_IP=$(curl -s --max-time 5 \
  -H "Metadata-Flavor: Google" \
  "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" \
  2>/dev/null || echo "<instance-public-ip>")

echo ""
echo "============================================================"
echo "  DPF cloud-init complete at $(date -u)"
echo ""
echo "  Portal:    http://$PUBLIC_IP:3000"
echo "  Admin:     admin@dpf.local"
echo "  Password:  see ADMIN_PASSWORD in $DPF_DIR/.env"
echo ""
if [ -z "${llm_base_url}" ]; then
echo "  IMPORTANT: LLM_BASE_URL is not configured."
echo "  AI features will not work until you set LLM_BASE_URL, LLM_MODEL,"
echo "  and EMBEDDING_MODEL in $DPF_DIR/.env, then run:"
echo "    cd $DPF_DIR && docker compose up -d"
fi
echo ""
echo "  Log:       /var/log/dpf-install.log"
echo "  Diagnose:  cd $DPF_DIR && bash install-dpf.sh doctor"
echo "============================================================"
