#!/usr/bin/env bash
# Configure CCIP bridge destinations for Avalanche, Arbitrum, Cronos ↔ Chain 138.
# Step A: On Chain 138, add Avalanche/Arbitrum/Cronos as destinations
# Step B: On Avalanche/Arbitrum/Cronos, add Chain 138 as destination
# Requires: bridge addresses and CHAIN138_SELECTOR in .env; PRIVATE_KEY; Chain 138 RPC reachable for Step A.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source.
if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then
  # shellcheck disable=SC1090
  source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
  load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}"
elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$PROJECT_ROOT/.env"
  set +a
elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$REPO_ROOT/.env"
  set +a
fi

[[ -f "$SCRIPT_DIR/../lib/infura.sh" ]] && source "$SCRIPT_DIR/../lib/infura.sh"

# Chain selectors (decimal)
AVALANCHE_SELECTOR="${AVALANCHE_SELECTOR:-6433500567565415381}"
ARBITRUM_SELECTOR="${ARBITRUM_SELECTOR:-4949039107694359620}"
CRONOS_SELECTOR="${CRONOS_SELECTOR:-1456215246176062136}"
CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-138}"

CHAIN138_RPC="${RPC_URL_138:-${CHAIN138_RPC:-http://192.168.11.211:8545}}"
CHAIN138_RPC="${CHAIN138_RPC%$'\r'}"
CHAIN138_RPC="${CHAIN138_RPC%$'\n'}"
# Prefer explicit RPC; else Infura (INFURA_PROJECT_ID + optional INFURA_PROJECT_SECRET); else public
_avalanche_infura=$(build_infura_rpc "avalanche-mainnet" 2>/dev/null || true)
_arbitrum_infura=$(build_infura_rpc "arbitrum-mainnet" 2>/dev/null || true)
AVALANCHE_RPC="${AVALANCHE_RPC_URL:-${AVALANCHE_RPC:-${_avalanche_infura:-https://avalanche-c-chain.publicnode.com}}}"
ARBITRUM_RPC="${ARBITRUM_MAINNET_RPC:-${ARBITRUM_RPC:-${_arbitrum_infura:-https://arbitrum-one.publicnode.com}}}"
CRONOS_RPC="${CRONOS_RPC_URL:-${CRONOS_RPC:-https://evm.cronos.org}}"

WETH9_138="${CCIPWETH9_BRIDGE_CHAIN138:-}"
WETH10_138="${CCIPWETH10_BRIDGE_CHAIN138:-}"
WETH9_AVALANCHE="${CCIPWETH9_BRIDGE_AVALANCHE:-}"
WETH10_AVALANCHE="${CCIPWETH10_BRIDGE_AVALANCHE:-}"
WETH9_ARBITRUM="${CCIPWETH9_BRIDGE_ARBITRUM:-}"
WETH10_ARBITRUM="${CCIPWETH10_BRIDGE_ARBITRUM:-}"
WETH9_CRONOS="${CCIPWETH9_BRIDGE_CRONOS:-}"
WETH10_CRONOS="${CCIPWETH10_BRIDGE_CRONOS:-}"

[[ -n "$WETH9_138" ]] && WETH9_138="${WETH9_138,,}"
[[ -n "$WETH10_138" ]] && WETH10_138="${WETH10_138,,}"
_gas138="--legacy --gas-limit 250000 --gas-price 2000000000"
_gas_remote="--legacy --gas-limit 400000"

PRIVATE_KEY="${PRIVATE_KEY:-}"

DRY_RUN="${DRY_RUN:-0}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

run_or_echo() {
  if [[ "$DRY_RUN" = "1" ]]; then
    echo "  [DRY RUN] $*"
  else
    local _out
    if _out=$(eval "$*" 2>&1); then
      echo -e "  ${GREEN}OK${NC}"
      [[ -n "$_out" ]] && echo "    $_out"
    else
      echo -e "  ${RED}Failed${NC}" >&2
      echo "    $_out" >&2
      return 1
    fi
  fi
}

echo -e "${GREEN}=== Avalanche/Arbitrum/Cronos ↔ Chain 138 Bridge Configuration ===${NC}"
echo ""

if ! require_private_key_env; then
  exit 1
fi

if [[ -z "$WETH9_138" ]]; then
  echo -e "${RED}ERROR: CCIPWETH9_BRIDGE_CHAIN138 must be set in .env${NC}"
  exit 1
fi
if [[ -z "$WETH10_138" ]]; then
  echo -e "${YELLOW}NOTE: CCIPWETH10_BRIDGE_CHAIN138 not set; skipping WETH10 bridge configuration${NC}"
fi

echo "Step A: Chain 138 → add Avalanche, Arbitrum, Cronos as destinations"
echo "  (Requires Chain 138 RPC reachable: $CHAIN138_RPC)"
echo ""

# Step A: Chain 138 → Avalanche
if [[ -n "$WETH9_AVALANCHE" || -n "$WETH10_AVALANCHE" ]]; then
  echo "  Chain 138 → Avalanche:"
  [[ -n "$WETH9_AVALANCHE" ]]  && run_or_echo "cast send $WETH9_138 \"addDestination(uint64,address)\" $AVALANCHE_SELECTOR ${WETH9_AVALANCHE,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true
  [[ -n "$WETH10_AVALANCHE" && -n "$WETH10_138" ]] && run_or_echo "cast send $WETH10_138 \"addDestination(uint64,address)\" $AVALANCHE_SELECTOR ${WETH10_AVALANCHE,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true
fi
# Step A: Chain 138 → Arbitrum
if [[ -n "$WETH9_ARBITRUM" || -n "$WETH10_ARBITRUM" ]]; then
  echo "  Chain 138 → Arbitrum:"
  [[ -n "$WETH9_ARBITRUM" ]]  && run_or_echo "cast send $WETH9_138 \"addDestination(uint64,address)\" $ARBITRUM_SELECTOR ${WETH9_ARBITRUM,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true
  [[ -n "$WETH10_ARBITRUM" && -n "$WETH10_138" ]] && run_or_echo "cast send $WETH10_138 \"addDestination(uint64,address)\" $ARBITRUM_SELECTOR ${WETH10_ARBITRUM,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true
fi
# Step A: Chain 138 → Cronos
if [[ -n "$WETH9_CRONOS" || -n "$WETH10_CRONOS" ]]; then
  echo "  Chain 138 → Cronos:"
  [[ -n "$WETH9_CRONOS" ]]  && run_or_echo "cast send $WETH9_138 \"addDestination(uint64,address)\" $CRONOS_SELECTOR ${WETH9_CRONOS,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true
  [[ -n "$WETH10_CRONOS" && -n "$WETH10_138" ]] && run_or_echo "cast send $WETH10_138 \"addDestination(uint64,address)\" $CRONOS_SELECTOR ${WETH10_CRONOS,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY $_gas138" || true
fi

echo ""
echo "Step B: Avalanche/Arbitrum/Cronos → add Chain 138 as destination"
echo ""

# Step B: Avalanche → Chain 138
if [[ -n "$WETH9_AVALANCHE" || -n "$WETH10_AVALANCHE" ]]; then
  echo "  Avalanche → Chain 138:"
  [[ -n "$WETH9_AVALANCHE" ]]  && run_or_echo "cast send ${WETH9_AVALANCHE,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_138 --rpc-url $AVALANCHE_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true
  [[ -n "$WETH10_AVALANCHE" && -n "$WETH10_138" ]] && run_or_echo "cast send ${WETH10_AVALANCHE,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_138 --rpc-url $AVALANCHE_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true
fi
# Step B: Arbitrum → Chain 138
if [[ -n "$WETH9_ARBITRUM" || -n "$WETH10_ARBITRUM" ]]; then
  echo "  Arbitrum → Chain 138:"
  [[ -n "$WETH9_ARBITRUM" ]]  && run_or_echo "cast send ${WETH9_ARBITRUM,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_138 --rpc-url $ARBITRUM_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true
  [[ -n "$WETH10_ARBITRUM" && -n "$WETH10_138" ]] && run_or_echo "cast send ${WETH10_ARBITRUM,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_138 --rpc-url $ARBITRUM_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true
fi
# Step B: Cronos → Chain 138
if [[ -n "$WETH9_CRONOS" || -n "$WETH10_CRONOS" ]]; then
  echo "  Cronos → Chain 138:"
  [[ -n "$WETH9_CRONOS" ]]  && run_or_echo "cast send ${WETH9_CRONOS,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_138 --rpc-url $CRONOS_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true
  [[ -n "$WETH10_CRONOS" && -n "$WETH10_138" ]] && run_or_echo "cast send ${WETH10_CRONOS,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_138 --rpc-url $CRONOS_RPC --private-key \$PRIVATE_KEY $_gas_remote" || true
fi

echo ""
echo -e "${GREEN}Bridge configuration complete.${NC}"
echo "Next: Fund each bridge with LINK for CCIP fees if not already done."
