#!/usr/bin/env bash
# Verify CompliantWrappedToken (cW*) on all chains where addresses exist in .env.
# Skips CW*_MAINNET (use verify-mainnet-cw-etherscan.sh). Same constructor as DeployCWTokens.
#
# Requires: ETHERSCAN_API_KEY (Etherscan v2 / unified explorers); CRONOSCAN_API_KEY for Cronos.
#           CW_VERIFY_ADMIN or PRIVATE_KEY for constructor admin address.
#
# Usage: cd smom-dbis-138 && ./scripts/deployment/verify-multichain-cw-etherscan.sh
set -euo pipefail

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

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

if [[ -z "${ETHERSCAN_API_KEY:-}" ]]; then
  echo "ETHERSCAN_API_KEY not set" >&2
  exit 1
fi

ADMIN="${CW_VERIFY_ADMIN:-}"
if [[ -z "$ADMIN" && -n "${PRIVATE_KEY:-}" ]]; then
  ADMIN="$(cast wallet address --private-key "$PRIVATE_KEY")"
fi
if [[ -z "$ADMIN" || "$ADMIN" == "0x0000000000000000000000000000000000000000" ]]; then
  echo "Set CW_VERIFY_ADMIN or PRIVATE_KEY" >&2
  exit 1
fi

# Uppercase chain suffix -> forge --chain name (Foundry)
forge_chain() {
  case "$1" in
    BSC) echo bsc ;;
    POLYGON) echo polygon ;;
    GNOSIS) echo gnosis ;;
    OPTIMISM) echo optimism ;;
    BASE) echo base ;;
    ARBITRUM) echo arbitrum ;;
    AVALANCHE) echo avalanche ;;
    CELO) echo celo ;;
    CRONOS) echo cronos ;;
    *) echo "" ;;
  esac
}

# API key for forge (Cronos uses cronoscan)
api_key_for() {
  case "$1" in
    CRONOS) echo "${CRONOSCAN_API_KEY:-}" ;;
    *) echo "${ETHERSCAN_API_KEY}" ;;
  esac
}

# cWUSDT -> Wrapped cUSDT / cWUSDT
name_sym_from_cw() {
  local cw="$1"
  local core="${cw#CW}"
  echo "Wrapped c${core}|cW${core}"
}

OK=0
SKIP=0
FAIL=0

while IFS= read -r line; do
  [[ "$line" =~ ^CW[A-Z0-9]+_[A-Z0-9]+= ]] || continue
  key="${line%%=*}"
  addr="${line#*=}"
  [[ -z "$addr" || "$addr" == "0x0000000000000000000000000000000000000000" ]] && continue
  chain="${key##*_}"
  [[ "$chain" == "MAINNET" ]] && continue
  # Cronos: Foundry + Etherscan API v2 often errors ("chainid"); use verify-cronos-contracts.sh or explorer.cronos.org manual upload.
  [[ "$chain" == "CRONOS" ]] && { echo "  skip $key (Cronos: use verify-cronos-contracts.sh or CRONOS_VERIFICATION_RUNBOOK)"; SKIP=$((SKIP + 1)); continue; }

  fc="$(forge_chain "$chain")"
  if [[ -z "$fc" ]]; then
    echo "  skip $key (unknown chain suffix $chain)"
    SKIP=$((SKIP + 1))
    continue
  fi

  api="$(api_key_for "$chain")"
  if [[ -z "$api" ]]; then
    echo "  skip $key (no API key for $chain; set CRONOSCAN_API_KEY for Cronos)" >&2
    SKIP=$((SKIP + 1))
    continue
  fi

  cwpart="${key%_*}"
  IFS='|' read -r cname sym <<< "$(name_sym_from_cw "$cwpart")"
  enc="$(cast abi-encode "constructor(string,string,uint8,address)" "$cname" "$sym" 6 "$ADMIN")"

  echo "[$fc] $sym $addr ..."
  set +e
  out="$(forge verify-contract \
    --chain "$fc" \
    --num-of-optimizations 200 \
    --via-ir \
    --constructor-args "$enc" \
    --etherscan-api-key "$api" \
    "$addr" \
    "contracts/tokens/CompliantWrappedToken.sol:CompliantWrappedToken" 2>&1)"
  rc=$?
  set -e
  if [[ $rc -eq 0 ]]; then
    echo "  ok"
    OK=$((OK + 1))
  elif echo "$out" | grep -qiE 'already verified|Already Verified|Contract source code already verified'; then
    echo "  already verified"
    OK=$((OK + 1))
  else
    echo "  FAILED (exit $rc)" >&2
    echo "$out" >&2
    FAIL=$((FAIL + 1))
  fi
  sleep 1
done < <(env | grep '^CW[A-Z0-9]*_' | sort)

echo ""
echo "=== multichain cW*: ok/already=$OK skipped=$SKIP failed=$FAIL ==="
