#!/usr/bin/env bash
# Verify Ethereum Mainnet CWMultiTokenBridgeL2 (CW_BRIDGE_MAINNET) on Etherscan.
#
# Constructor: (sendRouter, receiveRouter, feeToken) — read from chain if unset.
#
# Usage:
#   cd smom-dbis-138 && ./scripts/deployment/verify-mainnet-cw-bridge-etherscan.sh
#   ./scripts/deployment/verify-mainnet-cw-bridge-etherscan.sh --dry-run
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"

DRY_RUN=false
for a in "$@"; do
  case "$a" in
    --dry-run) DRY_RUN=true ;;
  esac
done

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}"
elif [[ -f "$PROJECT_ROOT/.env" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$PROJECT_ROOT/.env"
  set +a
fi

[[ -n "${ETHERSCAN_API_KEY:-}" ]] || {
  echo "ETHERSCAN_API_KEY not set" >&2
  exit 1
}

RPC="${ETHEREUM_MAINNET_RPC:-${ETH_MAINNET_RPC_URL:-https://ethereum-rpc.publicnode.com}}"
BRIDGE="${CW_BRIDGE_MAINNET:-0x2bF74583206A49Be07E0E8A94197C12987AbD7B5}"

fetch_creation_ctor() {
  python3 - "$BRIDGE" "$ETHERSCAN_API_KEY" <<'PY'
import json, sys, urllib.request
bridge, api_key = sys.argv[1:3]
url = (
    "https://api.etherscan.io/v2/api?chainid=1&module=contract&action=getcontractcreation"
    f"&contractaddresses={bridge}&apikey={api_key}"
)
with urllib.request.urlopen(url, timeout=30) as resp:
    doc = json.load(resp)
rows = doc.get("result") or []
if not rows:
    raise SystemExit("Etherscan getcontractcreation returned no rows")
creation = (rows[0].get("creationBytecode") or "").lower().removeprefix("0x")
if len(creation) < 192:
    raise SystemExit("creationBytecode too short")
# constructor args are last 3 x 32-byte words
args_hex = creation[-192:]
words = [args_hex[i : i + 64] for i in range(0, 192, 64)]
for w in words:
    print("0x" + w[-40:])
PY
}

SEND="${CW_BRIDGE_MAINNET_SEND_ROUTER:-}"
RECV="${CW_BRIDGE_MAINNET_RECEIVE_ROUTER:-}"
FEE="${CW_BRIDGE_MAINNET_FEE_TOKEN:-}"
if [[ -z "$SEND" || -z "$RECV" || -z "$FEE" ]]; then
  mapfile -t _CTOR_ADDRS < <(fetch_creation_ctor 2>/dev/null || true)
  if [[ ${#_CTOR_ADDRS[@]} -eq 3 ]]; then
    SEND="${_CTOR_ADDRS[0]}"
    RECV="${_CTOR_ADDRS[1]}"
    FEE="${_CTOR_ADDRS[2]}"
    echo "Using deployment-time constructor args from Etherscan creation tx"
  else
    SEND="$(cast call "$BRIDGE" 'sendRouter()(address)' --rpc-url "$RPC")"
    RECV="$(cast call "$BRIDGE" 'receiveRouter()(address)' --rpc-url "$RPC")"
    FEE="$(cast call "$BRIDGE" 'feeToken()(address)' --rpc-url "$RPC")"
    echo "WARN: using live on-chain router fields (may differ from deploy immutables)" >&2
  fi
fi

CTOR="$(cast abi-encode 'constructor(address,address,address)' "$SEND" "$RECV" "$FEE")"

echo "=== Verify CWMultiTokenBridgeL2 (CW_BRIDGE_MAINNET) ==="
echo "  bridge=$BRIDGE"
echo "  sendRouter=$SEND"
echo "  receiveRouter=$RECV"
echo "  feeToken=$FEE"

export FOUNDRY_SRC="contracts/bridge,contracts/interfaces"
export FOUNDRY_OUT="out/scopes/bridge"
export FOUNDRY_CACHE_PATH="cache/scopes/bridge"

if $DRY_RUN; then
  echo "forge verify-contract --chain-id 1 --num-of-optimizations 200 --via-ir \\"
  echo "  --constructor-args \"$CTOR\" --etherscan-api-key \"\$ETHERSCAN_API_KEY\" \\"
  echo "  \"$BRIDGE\" contracts/bridge/CWMultiTokenBridgeL2.sol:CWMultiTokenBridgeL2"
  exit 0
fi

bash "$PROJECT_ROOT/scripts/forge/scope.sh" build bridge -q

set +e
out="$(forge verify-contract \
  --chain-id 1 \
  --num-of-optimizations 200 \
  --via-ir \
  --constructor-args "$CTOR" \
  --etherscan-api-key "$ETHERSCAN_API_KEY" \
  "$BRIDGE" \
  "contracts/bridge/CWMultiTokenBridgeL2.sol:CWMultiTokenBridgeL2" 2>&1)"
rc=$?
set -e
echo "$out"
if [[ $rc -eq 0 ]] || echo "$out" | grep -qiE 'already verified|Contract source code already verified'; then
  echo "OK: https://etherscan.io/address/$BRIDGE#code"
  exit 0
fi
exit "$rc"
