#!/usr/bin/env bash
# Unified Contract Deployment Script
# Supports both parallel and ordered deployment modes

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../lib/init.sh"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
FORGE_SCOPE_RUNNER=(bash "$PROJECT_ROOT/scripts/forge/scope.sh")
# 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

# Default values
MODE="${MODE:-ordered}"  # ordered or parallel
RPC_URL="${RPC_URL:-}"
PRIVATE_KEY="${PRIVATE_KEY:-}"
DRY_RUN="${DRY_RUN:-false}"

usage() {
    cat <<EOF
Usage: $0 [OPTIONS]

Deploy all contracts using unified deployment script.

Options:
    --mode MODE         Deployment mode: ordered or parallel (default: ordered)
    --rpc-url URL       RPC endpoint URL (default: http://localhost:8545)
    --private-key KEY   Deployer private key
    --dry-run           Show what would be deployed without executing
    --help              Show this help message

Examples:
    # Deploy in ordered mode (respects dependencies)
    $0 --mode ordered

    # Deploy in parallel mode (where dependencies allow)
    $0 --mode parallel

    # Dry run to see deployment plan
    $0 --dry-run
EOF
    exit 0
}

# Parse arguments
while [[ $# -gt 0 ]]; do
    case "$1" in
        --mode)
            MODE="$2"
            shift 2
            ;;
        --rpc-url)
            RPC_URL="$2"
            shift 2
            ;;
        --private-key)
            PRIVATE_KEY="$2"
            shift 2
            ;;
        --dry-run)
            DRY_RUN=true
            shift
            ;;
        --help)
            usage
            ;;
        *)
            echo "ERROR: Unknown option: $1" >&2
            usage
            ;;
    esac
done

if ! require_private_key_env "Use --private-key or set PRIVATE_KEY in smom-dbis-138/.env, repo .env, or ~/.secure-secrets/private-keys.env."; then
    exit 1
fi

RPC_URL="${RPC_URL:-${RPC_URL_138:-${CHAIN138_RPC_URL:-}}}"
if [ -z "$RPC_URL" ]; then
    log_error "ERROR: Chain 138 RPC not available. Use --rpc-url or set RPC_URL/RPC_URL_138/CHAIN138_RPC_URL."
    exit 1
fi

# Verify RPC endpoint
log_info "Verifying RPC endpoint..."
if ! curl -s -m 10 -X POST "$RPC_URL" -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' > /dev/null 2>&1; then
    log_error "Error: RPC endpoint is not accessible at $RPC_URL"
    exit 1
fi

log_success "✅ RPC endpoint is accessible"

# Export variables
export PRIVATE_KEY
export RPC_URL
export CCIP_ROUTER="${CCIP_ROUTER:-}"
export CCIP_FEE_TOKEN="${CCIP_FEE_TOKEN:-0x0000000000000000000000000000000000000000}"
export ORACLE_DESCRIPTION="${ORACLE_DESCRIPTION:-ETH/USD Price Feed}"
export ORACLE_HEARTBEAT="${ORACLE_HEARTBEAT:-60}"
export ORACLE_DEVIATION_THRESHOLD="${ORACLE_DEVIATION_THRESHOLD:-50}"

# Function to update .env file
update_env() {
    local key=$1
    local value=$2
    if [ "$DRY_RUN" = "true" ]; then
        echo "  [DRY RUN] Would set ${key}=${value}"
        return
    fi
    if grep -q "^${key}=" .env 2>/dev/null; then
        sed -i "s|^${key}=.*|${key}=${value}|" .env
    else
        echo "${key}=${value}" >> .env
    fi
}

# Function to deploy a contract
deploy_contract() {
    local name=$1
    local script=$2
    local sig="${3:-run()}"
    
    log_section "Deploying $name"
    if [ "$DRY_RUN" = "true" ]; then
        echo "  [DRY RUN] Would deploy: $script"
        return
    fi
    
    "${FORGE_SCOPE_RUNNER[@]}" script "$script" \
        --rpc-url "$RPC_URL" \
        --broadcast \
        --private-key "$PRIVATE_KEY" \
        --sig "$sig" \
        -vvv 2>&1 | tee "/tmp/deploy-${name}.log"
    
    # Extract address from log (simplified - may need adjustment)
    local address=$(grep -oP "Deployed to: \K0x[a-fA-F0-9]{40}" "/tmp/deploy-${name}.log" | tail -1 || echo "")
    if [ -n "$address" ]; then
        update_env "${name^^}_ADDRESS" "$address"
        log_success "✅ $name deployed at: $address"
    fi
}

echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🚀 Unified Contract Deployment"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Mode: $MODE"
echo "RPC URL: $RPC_URL"
echo "Dry Run: $DRY_RUN"
echo ""

if [ "$MODE" = "parallel" ]; then
    log_info "Deploying contracts in parallel mode..."
    # Deploy independent contracts in parallel
    deploy_contract "Multicall" "script/DeployMulticall.s.sol" &
    deploy_contract "CREATE2Factory" "script/DeployCREATE2Factory.s.sol" &
    deploy_contract "Oracle" "script/DeployOracle.s.sol" &
    wait
    log_success "✅ Parallel deployment complete"
else
    log_info "Deploying contracts in ordered mode (respecting dependencies)..."
    # Phase 1: Core utilities (no dependencies)
    deploy_contract "Multicall" "script/DeployMulticall.s.sol"
    deploy_contract "CREATE2Factory" "script/DeployCREATE2Factory.s.sol"
    
    # Phase 2: Oracle (no dependencies)
    deploy_contract "Oracle" "script/DeployOracle.s.sol"
    
    # Phase 3: Governance (may depend on oracle)
    if [ -f "script/DeployMultiSig.s.sol" ]; then
        deploy_contract "MultiSig" "script/DeployMultiSig.s.sol"
    fi
    
    log_success "✅ Ordered deployment complete"
fi

echo ""
log_success "🎉 All contracts deployed successfully!"
