#!/usr/bin/env bash
# ==============================================================================
# GoodGo Platform — Cloudflare DNS Setup
# Adds DNS records for platform.goodgo.vn, api.goodgo.vn, grafana.goodgo.vn
#
# Prerequisites:
#   export CF_API_TOKEN="your-cloudflare-api-token"
#   export CF_ZONE_ID="your-goodgo-vn-zone-id"
#
# Usage:
#   ./infra/cloudflare-dns.sh
#   ./infra/cloudflare-dns.sh --dry-run     # Preview without creating
#   ./infra/cloudflare-dns.sh --delete       # Remove records
# ==============================================================================

set -euo pipefail

# ── Configuration ─────────────────────────────────────────────────────────────
CF_API_TOKEN="${CF_API_TOKEN:?Error: Set CF_API_TOKEN environment variable}"
CF_ZONE_ID="${CF_ZONE_ID:?Error: Set CF_ZONE_ID environment variable}"
TARGET_IP="${TARGET_IP:-185.225.232.65}"
CF_API="https://api.cloudflare.com/client/v4"
DRY_RUN=false
DELETE=false

# Parse flags
for arg in "$@"; do
  case "$arg" in
    --dry-run) DRY_RUN=true ;;
    --delete)  DELETE=true ;;
  esac
done

# DNS records to manage
declare -a SUBDOMAINS=("platform" "api" "grafana")

# ── Colors ────────────────────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

log()  { echo -e "${GREEN}[DNS]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
err()  { echo -e "${RED}[ERROR]${NC} $*" >&2; }
info() { echo -e "${CYAN}[INFO]${NC} $*"; }

# ── Helpers ───────────────────────────────────────────────────────────────────
cf_api() {
  local method="$1"
  local endpoint="$2"
  shift 2
  curl -s -X "$method" \
    "${CF_API}${endpoint}" \
    -H "Authorization: Bearer ${CF_API_TOKEN}" \
    -H "Content-Type: application/json" \
    "$@"
}

get_record_id() {
  local name="$1"
  cf_api GET "/zones/${CF_ZONE_ID}/dns_records?type=A&name=${name}.goodgo.vn" \
    | jq -r '.result[0].id // empty'
}

# ── Verify API Token ─────────────────────────────────────────────────────────
log "Verifying Cloudflare API token..."
VERIFY=$(cf_api GET "/user/tokens/verify")
if [ "$(echo "$VERIFY" | jq -r '.success')" != "true" ]; then
  err "Invalid Cloudflare API token!"
  echo "$VERIFY" | jq .
  exit 1
fi
log "API token verified."

# ── Verify Zone ──────────────────────────────────────────────────────────────
ZONE_NAME=$(cf_api GET "/zones/${CF_ZONE_ID}" | jq -r '.result.name')
if [ "$ZONE_NAME" != "goodgo.vn" ]; then
  err "Zone ID does not match goodgo.vn! Got: ${ZONE_NAME}"
  exit 1
fi
log "Zone verified: ${ZONE_NAME}"

# ── Process DNS Records ─────────────────────────────────────────────────────
echo ""
log "=========================================="
if $DELETE; then
  log " Deleting DNS records"
elif $DRY_RUN; then
  log " DRY RUN — no changes will be made"
else
  log " Creating/Updating DNS records"
fi
log " Target IP: ${TARGET_IP}"
log "=========================================="
echo ""

for sub in "${SUBDOMAINS[@]}"; do
  FQDN="${sub}.goodgo.vn"
  EXISTING_ID=$(get_record_id "$sub")

  if $DELETE; then
    if [ -n "$EXISTING_ID" ]; then
      if $DRY_RUN; then
        info "[DRY RUN] Would delete: ${FQDN} (ID: ${EXISTING_ID})"
      else
        RESULT=$(cf_api DELETE "/zones/${CF_ZONE_ID}/dns_records/${EXISTING_ID}")
        if [ "$(echo "$RESULT" | jq -r '.success')" = "true" ]; then
          log "Deleted: ${FQDN}"
        else
          err "Failed to delete ${FQDN}: $(echo "$RESULT" | jq -r '.errors[0].message')"
        fi
      fi
    else
      warn "Record not found: ${FQDN} — skipping delete"
    fi
    continue
  fi

  RECORD_DATA=$(cat <<EOF
{
  "type": "A",
  "name": "${sub}",
  "content": "${TARGET_IP}",
  "ttl": 1,
  "proxied": true,
  "comment": "GoodGo Platform — managed by infra/cloudflare-dns.sh"
}
EOF
)

  if [ -n "$EXISTING_ID" ]; then
    # Update existing record
    if $DRY_RUN; then
      info "[DRY RUN] Would update: ${FQDN} → ${TARGET_IP} (Proxied, ID: ${EXISTING_ID})"
    else
      RESULT=$(cf_api PUT "/zones/${CF_ZONE_ID}/dns_records/${EXISTING_ID}" -d "$RECORD_DATA")
      if [ "$(echo "$RESULT" | jq -r '.success')" = "true" ]; then
        log "Updated: ${FQDN} → ${TARGET_IP} (Proxied)"
      else
        err "Failed to update ${FQDN}: $(echo "$RESULT" | jq -r '.errors[0].message')"
      fi
    fi
  else
    # Create new record
    if $DRY_RUN; then
      info "[DRY RUN] Would create: ${FQDN} → ${TARGET_IP} (Proxied)"
    else
      RESULT=$(cf_api POST "/zones/${CF_ZONE_ID}/dns_records" -d "$RECORD_DATA")
      if [ "$(echo "$RESULT" | jq -r '.success')" = "true" ]; then
        NEW_ID=$(echo "$RESULT" | jq -r '.result.id')
        log "Created: ${FQDN} → ${TARGET_IP} (Proxied) [ID: ${NEW_ID}]"
      else
        err "Failed to create ${FQDN}: $(echo "$RESULT" | jq -r '.errors[0].message')"
      fi
    fi
  fi
done

# ── Verify DNS ───────────────────────────────────────────────────────────────
if ! $DRY_RUN && ! $DELETE; then
  echo ""
  log "Verifying DNS records..."
  echo ""
  for sub in "${SUBDOMAINS[@]}"; do
    FQDN="${sub}.goodgo.vn"
    RECORD=$(cf_api GET "/zones/${CF_ZONE_ID}/dns_records?type=A&name=${FQDN}")
    IP=$(echo "$RECORD" | jq -r '.result[0].content // "NOT FOUND"')
    PROXIED=$(echo "$RECORD" | jq -r '.result[0].proxied // "N/A"')
    info "${FQDN} → ${IP} (proxied: ${PROXIED})"
  done
fi

echo ""
log "=========================================="
log " DNS setup complete!"
if ! $DELETE; then
  log ""
  log " Cloudflare SSL/TLS settings (manual):"
  log "   - SSL mode: Full (Strict)"
  log "   - Always Use HTTPS: ON"
  log "   - Minimum TLS: 1.2"
  log "   - HTTP/2: ON"
  log "   - Brotli: ON"
  log ""
  log " Generate Origin Certificate at:"
  log "   Cloudflare Dashboard → SSL/TLS → Origin Server"
  log "   Save as: /etc/ssl/goodgo/origin.pem"
  log "           /etc/ssl/goodgo/origin-key.pem"
fi
log "=========================================="
