#!/usr/bin/env bash

set -e

# Generate Genesis for ChainID 138 - DeFi Oracle Meta Mainnet
# This script generates validator keys and creates the genesis.json with IBFT 2.0

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../lib/init.sh"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
CONFIG_DIR="$PROJECT_ROOT/config"
KEYS_DIR="$PROJECT_ROOT/keys"
VALIDATORS_DIR="$KEYS_DIR/validators"
ORACLE_DIR="$KEYS_DIR/oracle"


# Configuration
CHAIN_ID=138
BLOCK_PERIOD=2
EPOCH_LENGTH=30000
REQUEST_TIMEOUT=10
GAS_LIMIT="0x1c9c380"
NUM_VALIDATORS=4

log_success "Generating genesis for ChainID ${CHAIN_ID} - DeFi Oracle Meta Mainnet"

# Check if Besu is installed
if ! command -v besu &> /dev/null; then
    log_error "Error: Besu CLI not found. Please install Besu."
    echo "Visit: https://besu.hyperledger.org/en/stable/HowTo/Get-Started/Installation-Options/"
    exit 1
fi

# Create directories
mkdir -p "$VALIDATORS_DIR"
mkdir -p "$ORACLE_DIR"
mkdir -p "$CONFIG_DIR"

# Generate validator keys
log_warn "Generating ${NUM_VALIDATORS} validator keys..."
VALIDATOR_ADDRESSES=()
for i in $(seq 1 $NUM_VALIDATORS); do
    VALIDATOR_DIR="$VALIDATORS_DIR/validator-$i"
    mkdir -p "$VALIDATOR_DIR"
    
    # Generate key pair
    besu operator generate-blockchain-config \
        --config-file="$CONFIG_DIR/genesis-template.json" \
        --to="$VALIDATOR_DIR" \
        --private-key-file-name=key.priv 2>/dev/null || \
    besu public-key export-address \
        --node-private-key-file="$VALIDATOR_DIR/key.priv" > "$VALIDATOR_DIR/address.txt" 2>/dev/null || \
    {
        # Fallback: use openssl to generate keys if Besu tooling is limited
        openssl ecparam -genkey -name secp256k1 -noout -out "$VALIDATOR_DIR/key.pem" 2>/dev/null
        # Extract public key and derive address (simplified)
        openssl ec -in "$VALIDATOR_DIR/key.pem" -pubout -out "$VALIDATOR_DIR/pubkey.pem" 2>/dev/null
    }
    
    # For now, we'll generate keys using a simpler method
    # In production, use proper HSM/KMS key generation
    if [ ! -f "$VALIDATOR_DIR/key.priv" ]; then
        # Generate a private key (32 bytes hex)
        PRIVATE_KEY=$(openssl rand -hex 32)
        echo "$PRIVATE_KEY" > "$VALIDATOR_DIR/key.priv"
        log_success "Generated validator $i key"
    fi
    
    # Note: In production, use Besu's operator generate-blockchain-config
    # which properly generates keys and addresses
done

# Generate oracle key
log_warn "Generating oracle key..."
ORACLE_PRIVATE_KEY=$(openssl rand -hex 32)
echo "$ORACLE_PRIVATE_KEY" > "$ORACLE_DIR/key.priv"
log_success "Generated oracle key"

# Generate IBFT extraData
# Note: This is a placeholder. In production, use Besu's operator generate-blockchain-config
# which generates the proper RLP-encoded extraData with validator addresses
log_warn "Generating IBFT extraData..."
EXTRA_DATA="0x"

# Create genesis.json
log_warn "Creating genesis.json..."
cat > "$CONFIG_DIR/genesis.json" <<EOF
{
  "config": {
    "chainId": ${CHAIN_ID},
    "berlinBlock": 0,
    "londonBlock": 0,
    "istanbulBlock": 0,
    "clique": null,
    "ibft2": {
      "blockperiodseconds": ${BLOCK_PERIOD},
      "epochlength": ${EPOCH_LENGTH},
      "requesttimeoutseconds": ${REQUEST_TIMEOUT}
    },
    "ethash": {}
  },
  "nonce": "0x0",
  "timestamp": "0x$(printf '%x' $(date +%s))",
  "gasLimit": "${GAS_LIMIT}",
  "difficulty": "0x1",
  "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "alloc": {
    "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb": {
      "balance": "0xde0b6b3a7640000"
    }
  },
  "extraData": "${EXTRA_DATA}",
  "number": "0x0",
  "gasUsed": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
EOF

log_success "Genesis file created at: $CONFIG_DIR/genesis.json"
log_warn "Note: extraData must be generated using Besu's operator generate-blockchain-config"
log_warn "with the actual validator addresses for production deployment."

# Create a template for proper genesis generation
cat > "$CONFIG_DIR/genesis-template.json" <<EOF
{
  "genesis": {
    "config": {
      "chainId": ${CHAIN_ID},
      "berlinBlock": 0,
      "londonBlock": 0,
      "istanbulBlock": 0,
      "ibft2": {
        "blockperiodseconds": ${BLOCK_PERIOD},
        "epochlength": ${EPOCH_LENGTH},
        "requesttimeoutseconds": ${REQUEST_TIMEOUT}
      }
    },
    "nonce": "0x0",
    "timestamp": "0x0",
    "gasLimit": "${GAS_LIMIT}",
    "difficulty": "0x1",
    "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
    "coinbase": "0x0000000000000000000000000000000000000000",
    "alloc": {}
  },
  "blockchain": {
    "nodes": {
      "generate": true,
      "count": ${NUM_VALIDATORS}
    }
  }
}
EOF

log_success "Setup complete!"
log_warn "Next steps:"
echo "1. Review and update genesis.json with actual validator addresses"
echo "2. Generate proper IBFT extraData using: besu operator generate-blockchain-config"
echo "3. Store validator keys securely (Azure Key Vault for production)"
echo "4. Deploy infrastructure using Terraform"

