#!/bin/bash
# Coolify Infrastructure Setup via Hetzner Cloud API
set -euo pipefail

# Load API key from services.env
CRED_FILE="${HOME}/.openclaw/workspace/.credentials/services.env"
HETZNER_TOKEN=$(grep '^COOLIFY_HETZNER_API_KEY=' "$CRED_FILE" | cut -d= -f2- || true)

if [ -z "$HETZNER_TOKEN" ]; then
  echo "ERROR: COOLIFY_HETZNER_API_KEY not found in services.env"
  exit 1
fi

API="https://api.hetzner.cloud/v1"
AUTH="Authorization: Bearer $HETZNER_TOKEN"

hcloud() {
  curl -s -H "$AUTH" -H "Content-Type: application/json" "$@"
}

echo "=== Coolify Infrastructure Setup ==="

# Step 1: Upload SSH keys
echo ""
echo "--- Step 1: SSH Keys ---"

# User's key
USER_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFshMhXwS0FQFPlITipshvNKrV8sA52ZFlnaoHd1thKg dominik@nb-01"
# OpenClaw key
OPENCLAW_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL+i4Nn0Nc1ovqHXmbyekxCigT2Qn6RD1cdbKkW727Yl openclaw@openclaw-vm"

# Check if keys already exist
EXISTING_KEYS=$(hcloud "$API/ssh_keys" | jq -r '.ssh_keys[].name' 2>/dev/null || true)

upload_key() {
  local name="$1" key="$2"
  if echo "$EXISTING_KEYS" | grep -q "^${name}$"; then
    hcloud "$API/ssh_keys" | jq -r ".ssh_keys[] | select(.name==\"$name\") | .id"
  else
    echo "  Uploading key '$name'..." >&2
    RESP=$(hcloud -X POST "$API/ssh_keys" -d "{\"name\":\"$name\",\"public_key\":\"$key\"}")
    local kid=$(echo "$RESP" | jq -r '.ssh_key.id')
    if [ "$kid" = "null" ] || [ -z "$kid" ]; then
      echo "  ERROR: $(echo "$RESP" | jq -r '.error.message // "Unknown error"')" >&2
      exit 1
    fi
    echo "  Uploaded: ID $kid" >&2
    echo "$kid"
  fi
}

USER_KEY_ID=$(upload_key "dominik-nb01" "$USER_KEY")
OPENCLAW_KEY_ID=$(upload_key "openclaw-vm" "$OPENCLAW_KEY")

echo "  User key ID: $USER_KEY_ID"
echo "  OpenClaw key ID: $OPENCLAW_KEY_ID"

# Step 2: Create Network
echo ""
echo "--- Step 2: Private Network ---"

EXISTING_NET=$(hcloud "$API/networks" | jq -r '.networks[] | select(.name=="coolify-net") | .id' 2>/dev/null || echo "")

if [ -n "$EXISTING_NET" ]; then
  echo "  Network 'coolify-net' already exists: ID $EXISTING_NET"
  NET_ID="$EXISTING_NET"
else
  echo "  Creating network 'coolify-net' (10.0.0.0/16)..."
  RESP=$(hcloud -X POST "$API/networks" -d '{
    "name": "coolify-net",
    "ip_range": "10.0.0.0/16",
    "subnets": [{"type": "cloud", "network_zone": "eu-central", "ip_range": "10.0.1.0/24"}]
  }')
  NET_ID=$(echo "$RESP" | jq '.network.id')
  if [ "$NET_ID" = "null" ] || [ -z "$NET_ID" ]; then
    echo "  ERROR: $(echo "$RESP" | jq -r '.error.message // "Unknown error"')"
    exit 1
  fi
  echo "  Created: ID $NET_ID"
fi

# Step 3: Create Servers
echo ""
echo "--- Step 3: Servers ---"

create_server() {
  local name="$1"
  
  EXISTING=$(hcloud "$API/servers" | jq -r ".servers[] | select(.name==\"$name\") | .id" 2>/dev/null || echo "")
  if [ -n "$EXISTING" ]; then
    echo "  Server '$name' already exists: ID $EXISTING"
    IP=$(hcloud "$API/servers/$EXISTING" | jq -r '.server.public_net.ipv4.ip')
    echo "  IP: $IP"
    return
  fi
  
  echo "  Creating server '$name' (CAX11, ARM64, Ubuntu 24.04, fsn1)..."
  RESP=$(hcloud -X POST "$API/servers" -d "{
    \"name\": \"$name\",
    \"server_type\": \"cax11\",
    \"image\": \"ubuntu-24.04\",
    \"location\": \"fsn1\",
    \"ssh_keys\": [$USER_KEY_ID, $OPENCLAW_KEY_ID],
    \"networks\": [$NET_ID],
    \"public_net\": {\"enable_ipv4\": true, \"enable_ipv6\": true},
    \"labels\": {\"project\": \"coolify\", \"role\": \"$(echo $name | sed 's/coolify-//')\"}
  }")
  
  SERVER_ID=$(echo "$RESP" | jq '.server.id')
  IP=$(echo "$RESP" | jq -r '.server.public_net.ipv4.ip')
  
  if [ "$SERVER_ID" = "null" ] || [ -z "$SERVER_ID" ]; then
    echo "  ERROR: $(echo "$RESP" | jq -r '.error.message // "Unknown error"')"
    exit 1
  fi
  
  echo "  Created: ID $SERVER_ID, IP $IP"
}

create_server "coolify-1"
create_server "coolify-2"

# Step 4: Create Firewall
echo ""
echo "--- Step 4: Firewall ---"

EXISTING_FW=$(hcloud "$API/firewalls" | jq -r '.firewalls[] | select(.name=="coolify-fw") | .id' 2>/dev/null || echo "")

if [ -n "$EXISTING_FW" ]; then
  echo "  Firewall 'coolify-fw' already exists: ID $EXISTING_FW"
else
  echo "  Creating firewall 'coolify-fw'..."
  RESP=$(hcloud -X POST "$API/firewalls" -d '{
    "name": "coolify-fw",
    "rules": [
      {"direction": "in", "protocol": "tcp", "port": "22", "source_ips": ["0.0.0.0/0", "::/0"], "description": "SSH"},
      {"direction": "in", "protocol": "tcp", "port": "80", "source_ips": ["0.0.0.0/0", "::/0"], "description": "HTTP"},
      {"direction": "in", "protocol": "tcp", "port": "443", "source_ips": ["0.0.0.0/0", "::/0"], "description": "HTTPS"},
      {"direction": "in", "protocol": "tcp", "port": "8000", "source_ips": ["0.0.0.0/0", "::/0"], "description": "Coolify UI"}
    ]
  }')
  FW_ID=$(echo "$RESP" | jq '.firewall.id')
  echo "  Created: ID $FW_ID"
  
  # Apply to both servers
  echo "  Applying firewall to servers..."
  SERVER_IDS=$(hcloud "$API/servers" | jq '[.servers[] | select(.name | startswith("coolify-")) | .id]')
  for SID in $(echo "$SERVER_IDS" | jq -r '.[]'); do
    hcloud -X POST "$API/firewalls/$FW_ID/actions/apply_to_resources" \
      -d "{\"apply_to\": [{\"type\": \"server\", \"server\": {\"id\": $SID}}]}" > /dev/null
    echo "    Applied to server $SID"
  done
fi

# Summary
echo ""
echo "=== DONE ==="
echo ""
echo "Servers:"
for name in coolify-1 coolify-2; do
  IP=$(hcloud "$API/servers" | jq -r ".servers[] | select(.name==\"$name\") | .public_net.ipv4.ip")
  PRIV_IP=$(hcloud "$API/servers" | jq -r ".servers[] | select(.name==\"$name\") | .private_net[0].ip // \"pending\"")
  echo "  $name: public=$IP private=$PRIV_IP"
done
echo ""
echo "Next: Wait ~60s for servers to boot, then install Coolify on coolify-1"
