#!/usr/bin/env bash
# Verify all deployed contracts on Blockscout
# Usage: ./verify-all-contracts.sh [compiler-version]

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
SOURCE_PROJECT="${SOURCE_PROJECT:-/home/intlc/projects/smom-dbis-138}"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_section() { echo -e "${CYAN}════════════════════════════════════════${NC}"; }

# Configuration
RPC_URL="https://rpc-core.d-bis.org"
VERIFIER_URL="https://explorer.d-bis.org/api"
COMPILER_VERSION="${1:-0.8.20}"
CHAIN_ID=138

# Load environment
if [ -f "$SOURCE_PROJECT/.env" ]; then
    source "$SOURCE_PROJECT/.env" 2>/dev/null || true
fi

PRIVATE_KEY="${PRIVATE_KEY:-}"
if [ -z "$PRIVATE_KEY" ]; then
    log_error "PRIVATE_KEY not set. Set it in $SOURCE_PROJECT/.env or export it."
    exit 1
fi

# Ensure PRIVATE_KEY has 0x prefix
if [[ ! "$PRIVATE_KEY" =~ ^0x ]]; then
    export PRIVATE_KEY="0x$PRIVATE_KEY"
fi

log_section
log_info "Contract Verification on Blockscout"
log_info "ChainID: $CHAIN_ID"
log_info "Compiler Version: $COMPILER_VERSION"
log_section
echo ""

# Contract addresses to verify
declare -A CONTRACTS=(
    ["Oracle Proxy"]="0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6"
    ["Oracle Aggregator"]="0x99b3511a2d315a497c8112c1fdd8d508d4b1e506"
    ["CCIP Router"]="0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e"
    ["CCIP Sender"]="0x105F8A15b819948a89153505762444Ee9f324684"
    ["CCIPWETH9Bridge"]="0x89dd12025bfCD38A168455A44B400e913ED33BE2"
    ["CCIPWETH10Bridge"]="0xe0E93247376aa097dB308B92e6Ba36bA015535D0"
    ["Price Feed Keeper"]="0xD3AD6831aacB5386B8A25BB8D8176a6C8a026f04"
)

# Pre-deployed contracts (not verified)
declare -A PREDEPLOYED=(
    ["WETH9"]="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
    ["WETH10"]="0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f"
    ["Multicall"]="0x99b3511a2d315a497c8112c1fdd8d508d4b1e506"
)

# Check if contract is already verified on Blockscout
check_verification_status() {
    local address="$1"
    local name="$2"
    
    log_info "Checking verification status for $name ($address)..."
    
    # Check Blockscout API for verification status
    local response=$(curl -s "${VERIFIER_URL%/api}/api/v2/smart-contracts/${address}" 2>/dev/null || echo "")
    
    if echo "$response" | grep -q '"is_verified":true' || echo "$response" | grep -q '"verified":true'; then
        log_success "$name is already verified"
        return 0
    else
        log_warn "$name is not verified"
        return 1
    fi
}

# Verify a contract
verify_contract() {
    local name="$1"
    local address="$2"
    local contract_name="$3"
    local constructor_args="${4:-}"
    
    log_info ""
    log_section
    log_info "Verifying: $name"
    log_info "Address: $address"
    log_info "Contract: $contract_name"
    log_section
    echo ""
    
    # Check if already verified
    if check_verification_status "$address" "$name"; then
        return 0
    fi
    
    # Build verify command
    local verify_cmd="forge verify-contract \
        $address \
        $contract_name \
        --chain-id $CHAIN_ID \
        --rpc-url $RPC_URL \
        --verifier blockscout \
        --verifier-url $VERIFIER_URL \
        --compiler-version $COMPILER_VERSION"
    
    if [ -n "$constructor_args" ]; then
        verify_cmd="$verify_cmd --constructor-args $constructor_args"
    fi
    
    log_info "Running verification command..."
    log_info "Command: $verify_cmd"
    echo ""
    
    # Run verification
    if eval "$verify_cmd"; then
        log_success "$name verification successful!"
        return 0
    else
        log_error "$name verification failed"
        return 1
    fi
}

# Main verification process
cd "$SOURCE_PROJECT" || exit 1

VERIFIED_COUNT=0
FAILED_COUNT=0
SKIPPED_COUNT=0

log_info "Starting contract verification process..."
log_info "Total contracts to check: ${#CONTRACTS[@]}"
echo ""

# Verify each contract
for contract_name in "${!CONTRACTS[@]}"; do
    address="${CONTRACTS[$contract_name]}"
    
    # Map contract names to Solidity contract names
    case "$contract_name" in
        "Oracle Proxy")
            solidity_name="Proxy"
            ;;
        "Oracle Aggregator")
            solidity_name="Aggregator"
            ;;
        "CCIP Router")
            solidity_name="Router"
            log_warn "CCIP Router may require special verification (using official Chainlink contracts)"
            continue
            ;;
        "CCIP Sender")
            solidity_name="CCIPSender"
            ;;
        "CCIPWETH9Bridge")
            solidity_name="CCIPWETH9Bridge"
            ;;
        "CCIPWETH10Bridge")
            solidity_name="CCIPWETH10Bridge"
            ;;
        "Price Feed Keeper")
            solidity_name="PriceFeedKeeper"
            ;;
        *)
            log_warn "Unknown contract type: $contract_name, skipping..."
            SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
            continue
            ;;
    esac
    
    if verify_contract "$contract_name" "$address" "$solidity_name"; then
        VERIFIED_COUNT=$((VERIFIED_COUNT + 1))
    else
        FAILED_COUNT=$((FAILED_COUNT + 1))
    fi
    
    # Small delay between verifications
    sleep 2
done

# Summary
log_section
log_info "Verification Summary"
log_section
log_success "Verified: $VERIFIED_COUNT"
if [ $FAILED_COUNT -gt 0 ]; then
    log_error "Failed: $FAILED_COUNT"
fi
if [ $SKIPPED_COUNT -gt 0 ]; then
    log_warn "Skipped: $SKIPPED_COUNT"
fi

log_info ""
log_info "Pre-deployed contracts (not verified):"
for contract_name in "${!PREDEPLOYED[@]}"; do
    log_info "  - $contract_name: ${PREDEPLOYED[$contract_name]}"
done

echo ""
log_info "View contracts on Blockscout:"
log_info "  https://explorer.d-bis.org/address/<CONTRACT_ADDRESS>"
echo ""

