#cloud-config
# Cloud-init configuration for Besu node setup (Phase 1)
# Installs: Docker Engine, NVM, Node 22 LTS, JDK 17, and Besu

package_update: true
package_upgrade: true

packages:
  - apt-transport-https
  - ca-certificates
  - curl
  - gnupg
  - lsb-release
  - jq
  - wget
  - unzip
  - git
  - build-essential

write_files:
  - path: /opt/besu/setup.sh
    content: |
      #!/bin/bash
      set -e
      
      NODE_TYPE="${node_type}"
      NODE_INDEX="${node_index}"
      CLUSTER_NAME="${cluster_name}"
      KEY_VAULT_ID="${key_vault_id}"
      GENESIS_FILE_PATH="${genesis_file_path}"
      ADMIN_USERNAME="${admin_username}"
      
      echo "Setting up Besu node: $NODE_TYPE-$NODE_INDEX"
      
      # Install Docker Engine
      if ! command -v docker &> /dev/null; then
        echo "Installing Docker Engine..."
        curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
        echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
        apt-get update
        apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
        systemctl enable docker
        systemctl start docker
        usermod -aG docker $ADMIN_USERNAME
        echo "Docker Engine installed successfully"
      fi
      
      # Install NVM (Node Version Manager)
      if [ ! -d "/home/$ADMIN_USERNAME/.nvm" ]; then
        echo "Installing NVM..."
        export NVM_DIR="/home/$ADMIN_USERNAME/.nvm"
        curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
        chown -R $ADMIN_USERNAME:$ADMIN_USERNAME /home/$ADMIN_USERNAME/.nvm
        echo 'export NVM_DIR="$HOME/.nvm"' >> /home/$ADMIN_USERNAME/.bashrc
        echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> /home/$ADMIN_USERNAME/.bashrc
        echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> /home/$ADMIN_USERNAME/.bashrc
        echo "NVM installed successfully"
      fi
      
      # Install Node.js 22 LTS via NVM
      echo "Installing Node.js 22 LTS..."
      export NVM_DIR="/home/$ADMIN_USERNAME/.nvm"
      [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
      su - $ADMIN_USERNAME -c "source ~/.nvm/nvm.sh && nvm install 22 && nvm alias default 22 && nvm use 22"
      echo "Node.js 22 LTS installed successfully"
      
      # Install JDK 17 (OpenJDK)
      if ! command -v java &> /dev/null || ! java -version 2>&1 | grep -q "17"; then
        echo "Installing JDK 17..."
        apt-get update
        apt-get install -y openjdk-17-jdk
        update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java
        echo "JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64" >> /etc/environment
        echo "JDK 17 installed successfully"
      fi
      
      # Install Azure CLI (if not already installed)
      if ! command -v az &> /dev/null; then
        echo "Installing Azure CLI..."
        curl -sL https://aka.ms/InstallAzureCLIDeb | bash
      fi
      
      # Create directories
      mkdir -p /opt/besu/{data,config,keys,logs}
      chown -R $ADMIN_USERNAME:$ADMIN_USERNAME /opt/besu
      
      # Download genesis file from storage (if URL provided)
      if [ -n "$GENESIS_FILE_PATH" ] && [[ "$GENESIS_FILE_PATH" == http* ]]; then
        echo "Downloading genesis file from $GENESIS_FILE_PATH..."
        wget -q -O /opt/besu/config/genesis.json "$GENESIS_FILE_PATH" || echo "Failed to download genesis file"
      fi
      
      # Configure Azure CLI authentication (Managed Identity)
      if [ -n "$KEY_VAULT_ID" ]; then
        echo "Configuring Azure authentication for Key Vault access..."
        # VMs use Managed Identity for Key Vault access
        # Azure CLI will use Managed Identity automatically
      fi
      
      # Download validator keys from Key Vault (if validator)
      if [ "$NODE_TYPE" == "validator" ] && [ -n "$KEY_VAULT_ID" ]; then
        echo "Downloading validator keys from Key Vault..."
        # Extract key vault name from ID
        KEY_VAULT_NAME=$(echo "$KEY_VAULT_ID" | sed 's/.*\/\([^/]*\)$/\1/')
        # Download keys using Azure CLI with Managed Identity
        # az keyvault secret show --vault-name "$KEY_VAULT_NAME" --name "validator-key-$NODE_INDEX" --query value -o tsv > /opt/besu/keys/validator-key.txt || echo "Failed to download key"
      fi
      
      # Ensure directories have correct permissions
      chown -R $ADMIN_USERNAME:$ADMIN_USERNAME /opt/besu
      
      # Verify installations
      echo "=== Installation Verification ==="
      docker --version
      su - $ADMIN_USERNAME -c "source ~/.nvm/nvm.sh && node --version && npm --version"
      java -version
      echo "=== Setup complete! ==="
    permissions: '0755'
    owner: root:root

  - path: /opt/besu/docker-compose.yml
    content: |
      version: '3.8'
      
      services:
        besu:
          image: hyperledger/besu:23.10.0
          container_name: besu-${node_type}-${node_index}
          restart: unless-stopped
          user: "${admin_username}"
          volumes:
            - /opt/besu/data:/data
            - /opt/besu/config:/config
            - /opt/besu/keys:/keys:ro
            - /opt/besu/logs:/logs
          ports:
            - "9545:9545"  # Metrics
            ${node_type == "validator" || node_type == "sentry" ? "- \"30303:30303\"  # P2P TCP\n            - \"30303:30303/udp\"  # P2P UDP" : ""}
            ${node_type == "rpc" ? "- \"8545:8545\"  # RPC HTTP\n            - \"8546:8546\"  # WebSocket" : ""}
          command:
            - /opt/besu/bin/besu
            - --config-file=/config/besu-config.toml
          environment:
            - BESU_OPTS=-Xmx4g -Xms4g
          networks:
            - besu-network
          logging:
            driver: "json-file"
            options:
              max-size: "10m"
              max-file: "3"
          healthcheck:
            test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9545/metrics"]
            interval: 30s
            timeout: 10s
            retries: 3
            start_period: 120s
      
      networks:
        besu-network:
          driver: bridge
    permissions: '0644'
    owner: ${admin_username}:${admin_username}

  - path: /etc/systemd/system/besu.service
    content: |
      [Unit]
      Description=Besu Node Service
      After=docker.service
      Requires=docker.service
      
      [Service]
      Type=oneshot
      RemainAfterExit=yes
      WorkingDirectory=/opt/besu
      ExecStart=/usr/bin/docker compose up -d
      ExecStop=/usr/bin/docker compose down
      Restart=on-failure
      RestartSec=10
      User=${admin_username}
      Group=${admin_username}
      
      [Install]
      WantedBy=multi-user.target
    permissions: '0644'
    owner: root:root

runcmd:
  - /opt/besu/setup.sh
  - systemctl daemon-reload
  - systemctl enable besu.service
  - systemctl start besu.service

final_message: "Besu node setup complete. Node type: ${node_type}, Index: ${node_index}. Docker, NVM, Node 22 LTS, and JDK 17 installed."

