#!/bin/bash
# Build NixOS image on remote Hetzner server (cross-platform builds)
# Usage: ./build-nixos-image-remote.sh [role] [location] [project_path]
# Output: SNAPSHOT_ID written to stdout on success

set -euo pipefail

# Configuration
ROLE="${1:-cp}"
LOCATION="${2:-nbg1}"
PROJECT_PATH="${3:-.}"
SSH_KEY="${SSH_KEY:-htz_ops}"
HCLOUD_TOKEN="${HCLOUD_TOKEN:?HCLOUD_TOKEN required}"

# Derived
TEMP_NAME="build-nixos-${ROLE}-$$"
FLAKE_DIR="workspaces/librecloud_hetzner/nixos"
TIMESTAMP=$(date -u +%Y-%m-%dT%H%M%SZ)
DESCRIPTION="nixos-${ROLE}-aarch64-${TIMESTAMP}"

echo "=== Building NixOS ${ROLE} image on Hetzner ==="
echo "Temp server: $TEMP_NAME | Role: $ROLE | Location: $LOCATION"

# Create temporary build server
echo "=== 1. Creating temp server $TEMP_NAME ==="
hcloud server create \
  --name "$TEMP_NAME" \
  --type cax11 \
  --location "$LOCATION" \
  --image debian-12 \
  --ssh-key "$SSH_KEY" > /dev/null

SERVER_ID=$(hcloud server describe "$TEMP_NAME" -o format='{{.ID}}')
SERVER_IP=$(hcloud server describe "$TEMP_NAME" -o format='{{.PublicNet.IPv4.IP}}')
echo "Created: $TEMP_NAME (ID=$SERVER_ID, IP=$SERVER_IP)"

cleanup() {
  echo "=== Cleanup: deleting server ==="
  hcloud server delete "$SERVER_ID" 2>/dev/null || true
  rm -f /tmp/build-remote-*.sh /tmp/project-build.tar.gz
}
trap cleanup EXIT

# Wait for SSH
echo "=== 2. Waiting for SSH connectivity ==="
SSH_READY=0
for i in $(seq 1 60); do
  if ssh -o StrictHostKeyChecking=no -o ConnectTimeout=3 -o BatchMode=yes root@"${SERVER_IP}" true 2>/dev/null; then
    echo "SSH ready after $((i*5)) seconds"
    SSH_READY=1
    break
  fi
  printf "."
  sleep 5
done

if [ "$SSH_READY" -eq 0 ]; then
  echo ""
  echo "ERROR: SSH timeout after 300 seconds"
  echo "Server: $SERVER_IP"
  echo "Check: ssh -o StrictHostKeyChecking=no root@${SERVER_IP}"
  exit 1
fi
echo ""

# Transfer project
echo "=== 3. Transferring project ==="
SSH_OPTS="-o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=10"

tar -czf /tmp/project-build.tar.gz \
  --exclude='.git/objects' \
  --exclude='.git/logs' \
  --exclude='.nix' \
  --exclude='result*' \
  --exclude='*.img' \
  --exclude='target' \
  --exclude='.coder' \
  -C "$PROJECT_PATH" .

SIZE=$(ls -lh /tmp/project-build.tar.gz | awk '{print $5}')
echo "Uploading $SIZE..."
scp $SSH_OPTS /tmp/project-build.tar.gz "root@${SERVER_IP}:/tmp/" || {
  echo "ERROR: Failed to upload project"
  exit 1
}

ssh $SSH_OPTS root@"${SERVER_IP}" "cd /tmp && tar -xzf project-build.tar.gz && rm project-build.tar.gz && echo 'Project extracted'" || {
  echo "ERROR: Failed to extract project"
  exit 1
}
echo "Project transferred"

# Install Nix and build
echo "=== 4. Installing Nix on server ==="
cat > /tmp/build-remote-install.sh << 'INSTALL_NIX'
#!/bin/bash
set -euo pipefail
apt-get update -qq
apt-get install -y -qq curl xz-utils
curl -L https://nixos.org/nix/install | bash -s -- --no-daemon --yes 2>/dev/null
export PATH="${HOME}/.nix-profile/bin:$PATH"
nix --version
INSTALL_NIX

scp $SSH_OPTS /tmp/build-remote-install.sh "root@${SERVER_IP}:/tmp/"
ssh $SSH_OPTS root@"${SERVER_IP}" bash /tmp/build-remote-install.sh

echo "=== 5. Building image ==="
cat > /tmp/build-remote-build.sh << BUILD_IMAGE
#!/bin/bash
set -euo pipefail
export PATH="\${HOME}/.nix-profile/bin:\$PATH"
export NIX_CONFIG="experimental-features = nix-command flakes"

cd /tmp
echo "Building ${ROLE} image..."
nix build "${FLAKE_DIR}#packages.aarch64-linux.${ROLE}-image" \
  --out-link "/tmp/nixos-${ROLE}-image" \
  --print-build-logs 2>&1 | tail -20

IMG=\$(find /tmp/nixos-${ROLE}-image -name "*.img" | head -1)
if [ -z "\$IMG" ]; then
  echo "ERROR: image not found"
  exit 1
fi
ls -lh "\$IMG"
echo "SUCCESS: Image built"
BUILD_IMAGE

scp $SSH_OPTS /tmp/build-remote-build.sh "root@${SERVER_IP}:/tmp/"
ssh $SSH_OPTS root@"${SERVER_IP}" bash /tmp/build-remote-build.sh

# Fetch image
echo "=== 6. Fetching image back ==="
mkdir -p /tmp/nixos-build
scp $SSH_OPTS "root@${SERVER_IP}:/tmp/nixos-${ROLE}-image/*.img" /tmp/nixos-build/ 2>/dev/null || {
  echo "ERROR: Failed to fetch image"
  exit 1
}
IMAGE_LOCAL=$(find /tmp/nixos-build -name "*.img" | head -1)
echo "Image: $(ls -lh "$IMAGE_LOCAL" | awk '{print $5, $9}')"

# Reboot and deploy
echo "=== 7. Rebooting into rescue ==="
hcloud server reboot "$SERVER_ID" --force
sleep 15

hcloud server enable-rescue "$SERVER_ID" --type linux64 --ssh-key "$SSH_KEY" > /dev/null
hcloud server reboot "$SERVER_ID"

echo "Waiting for rescue SSH..."
RESCUE_READY=0
for i in $(seq 1 60); do
  if ssh $SSH_OPTS -o ConnectTimeout=3 -o BatchMode=yes root@"${SERVER_IP}" true 2>/dev/null; then
    echo "Rescue ready"
    RESCUE_READY=1
    break
  fi
  printf "."
  sleep 5
done

if [ "$RESCUE_READY" -eq 0 ]; then
  echo ""
  echo "ERROR: Rescue SSH timeout"
  exit 1
fi
echo ""

# Write image to disk
echo "=== 8. Writing image to /dev/sda ==="
gzip -dc "$IMAGE_LOCAL" | ssh $SSH_OPTS root@"${SERVER_IP}" \
  "dd of=/dev/sda bs=4M conv=fsync status=progress"

echo "=== 9. Powering off ==="
hcloud server poweroff "$SERVER_ID"
sleep 15

echo "=== 10. Creating snapshot ==="
SNAPSHOT_ID=$(hcloud server create-image "$SERVER_ID" \
  --type snapshot \
  --description "$DESCRIPTION" \
  -o format='{{.ID}}')

echo ""
echo "════════════════════════════════════════"
echo "✓ BUILD SUCCESS"
echo "════════════════════════════════════════"
echo "SNAPSHOT_ID=$SNAPSHOT_ID"
echo ""
echo "Next: Update servers.ncl for role '$ROLE':"
echo "  image = \"$SNAPSHOT_ID\""
echo "════════════════════════════════════════"

# Keep snapshot, delete server
trap - EXIT
hcloud server delete "$SERVER_ID"
