#!/usr/bin/env bash

# Validate Deployment Configuration
# This script checks all deployment configurations for misconfigurations and gaps

set -e


# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../lib/init.sh"
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

ERRORS=0
WARNINGS=0

log_info "=== Deployment Configuration Validation ==="

# Function to check file exists
check_file() {
    local file=$1
    local description=$2
    if [ -f "$file" ]; then
        log_success "✅ ${description}: ${file}"
        return 0
    else
        log_error "❌ ${description}: ${file} (MISSING)"
        ((ERRORS++))
        return 1
    fi
}

# Function to check value in file
check_value() {
    local file=$1
    local pattern=$2
    local expected=$3
    local description=$4
    
    if [ ! -f "$file" ]; then
        log_error "❌ ${description}: File not found"
        ((ERRORS++))
        return 1
    fi
    
    local value=$(grep -E "$pattern" "$file" | head -1 | sed 's/.*://' | tr -d ' ,"' || echo "")
    if [ -z "$value" ]; then
        log_warn "⚠️  ${description}: Value not found"
        ((WARNINGS++))
        return 1
    fi
    
    if [ "$value" = "$expected" ]; then
        log_success "✅ ${description}: ${value} (correct)"
        return 0
    else
        log_error "❌ ${description}: ${value} (expected: ${expected})"
        ((ERRORS++))
        return 1
    fi
}

# Function to check if value exists (any value)
check_value_exists() {
    local file=$1
    local pattern=$2
    local description=$3
    
    if [ ! -f "$file" ]; then
        log_error "❌ ${description}: File not found"
        ((ERRORS++))
        return 1
    fi
    
    if grep -qE "$pattern" "$file"; then
        local value=$(grep -E "$pattern" "$file" | head -1)
        log_success "✅ ${description}: Found"
        return 0
    else
        log_error "❌ ${description}: Not found"
        ((ERRORS++))
        return 1
    fi
}

log_info "=== 1. Genesis Configuration ==="
check_file "config/genesis.json" "Genesis file"
if [ -f "config/genesis.json" ]; then
    # Check Chain ID
    CHAIN_ID=$(grep -oE '"chainId"[[:space:]]*:[[:space:]]*[0-9]+' config/genesis.json | grep -oE '[0-9]+' || echo "")
    if [ "$CHAIN_ID" = "138" ]; then
        log_success "✅ Chain ID: 138 (correct)"
    else
        log_error "❌ Chain ID: ${CHAIN_ID} (expected: 138)"
        ((ERRORS++))
    fi
    
    # Check consensus configuration
    if grep -q "qbft" config/genesis.json || grep -q "ibft2" config/genesis.json; then
        log_success "✅ QBFT-compatible consensus configured"
    else
        log_error "❌ Consensus configuration not found in genesis"
        ((ERRORS++))
    fi
    
    # Check validators
    VALIDATOR_COUNT=$(grep -oE '"validators"' config/genesis.json | wc -l || echo "0")
    if [ "$VALIDATOR_COUNT" -gt 0 ]; then
        log_success "✅ Validators configured"
    else
        log_error "❌ No validators found in genesis"
        ((ERRORS++))
    fi
fi

log_info "=== 2. Terraform Configuration ==="
check_file "terraform/main.tf" "Terraform main file"
check_file "terraform/variables.tf" "Terraform variables file"
check_file "terraform/terraform.tfvars" "Terraform variables values"

if [ -f "terraform/terraform.tfvars" ]; then
    # Check environment
    check_value_exists "terraform/terraform.tfvars" "environment" "Environment setting"
    # Check location
    check_value_exists "terraform/terraform.tfvars" "location" "Location setting"
    # Check cluster name
    check_value_exists "terraform/terraform.tfvars" "cluster_name" "Cluster name"
fi

log_info "=== 3. Kubernetes/Helm Configuration ==="
check_file "helm/besu-network/Chart.yaml" "Helm Chart"
check_file "helm/besu-network/values.yaml" "Helm base values"
check_file "helm/besu-network/values-validators.yaml" "Helm validators values"
check_file "helm/besu-network/values-sentries.yaml" "Helm sentries values"
check_file "helm/besu-network/values-rpc.yaml" "Helm RPC values"
check_file "k8s/base/namespace.yaml" "Kubernetes namespace"

# Check Helm values for Chain ID
if [ -f "helm/besu-network/values-validators.yaml" ]; then
    HELM_CHAIN_ID=$(grep -E "chainId|chain-id|CHAIN_ID" helm/besu-network/values-validators.yaml | grep -oE '[0-9]+' | head -1 || echo "")
    if [ -n "$HELM_CHAIN_ID" ] && [ "$HELM_CHAIN_ID" = "138" ]; then
        log_success "✅ Helm Chain ID: 138 (correct)"
    elif [ -n "$HELM_CHAIN_ID" ]; then
        log_error "❌ Helm Chain ID: ${HELM_CHAIN_ID} (expected: 138)"
        ((ERRORS++))
    else
        log_warn "⚠️  Helm Chain ID: Not explicitly set (may use default)"
        ((WARNINGS++))
    fi
fi

log_info "=== 4. Key Management ==="
if [ -d "keys/validators" ]; then
    VALIDATOR_KEY_COUNT=$(find keys/validators -name "key.priv" 2>/dev/null | wc -l || echo "0")
    if [ "$VALIDATOR_KEY_COUNT" -gt 0 ]; then
        log_success "✅ Validator keys found: ${VALIDATOR_KEY_COUNT}"
    else
        log_error "❌ No validator keys found"
        ((ERRORS++))
    fi
else
    log_error "❌ Validator keys directory not found"
    ((ERRORS++))
fi

if [ -d "keys/oracle" ]; then
    ORACLE_KEY_COUNT=$(find keys/oracle -name "key.priv" 2>/dev/null | wc -l || echo "0")
    if [ "$ORACLE_KEY_COUNT" -gt 0 ]; then
        log_success "✅ Oracle keys found: ${ORACLE_KEY_COUNT}"
    else
        log_warn "⚠️  No oracle keys found"
        ((WARNINGS++))
    fi
else
    log_warn "⚠️  Oracle keys directory not found"
    ((WARNINGS++))
fi

log_info "=== 5. Environment Configuration ==="
if [ -f ".env" ]; then
    log_success "✅ .env file exists"
    
    # Check required variables
    if grep -q "^PRIVATE_KEY=" .env; then
        log_success "✅ PRIVATE_KEY configured"
    else
        log_error "❌ PRIVATE_KEY not configured"
        ((ERRORS++))
    fi
    
    if grep -q "^RPC_URL=" .env; then
        RPC_URL=$(grep "^RPC_URL=" .env | cut -d'=' -f2- | tr -d '"' | tr -d "'")
        if [ -n "$RPC_URL" ]; then
            log_success "✅ RPC_URL configured: ${RPC_URL}"
        else
            log_warn "⚠️  RPC_URL is empty"
            ((WARNINGS++))
        fi
    else
        log_warn "⚠️  RPC_URL not configured"
        ((WARNINGS++))
    fi
else
    log_error "❌ .env file not found"
    ((ERRORS++))
fi

log_info "=== 6. Deployment Scripts ==="
check_file "scripts/deployment/deploy-all-ordered.sh" "Deployment script"
check_file "scripts/deployment/check-deployment-status.sh" "Status check script"
check_file "scripts/deployment/check-rpc-status.sh" "RPC status script"
check_file "scripts/deployment/start-local-testnet.sh" "Local testnet script"

log_info "=== 7. Contract Deployment Scripts ==="
check_file "script/DeployWETH.s.sol" "WETH deployment script"
check_file "script/DeployWETH10.s.sol" "WETH10 deployment script"
check_file "script/DeployCCIPRouter.s.sol" "CCIP Router deployment script"
check_file "script/DeployCCIPWETH9Bridge.s.sol" "CCIPWETH9Bridge deployment script"
check_file "script/DeployCCIPWETH10Bridge.s.sol" "CCIPWETH10Bridge deployment script"
check_file "script/DeployOracle.s.sol" "Oracle deployment script"
check_file "script/DeployMockLinkToken.s.sol" "Mock LINK Token deployment script"

log_info "=== 8. Network Configuration Files ==="
if [ -f "config/static-nodes.json" ]; then
    log_success "✅ static-nodes.json found"
    NODE_COUNT=$(grep -c "enode://" config/static-nodes.json 2>/dev/null || echo "0")
    if [ "$NODE_COUNT" -gt 0 ]; then
        log_success "✅ Static nodes configured: ${NODE_COUNT}"
    else
        log_warn "⚠️  No static nodes configured"
        ((WARNINGS++))
    fi
else
    log_warn "⚠️  static-nodes.json not found"
    ((WARNINGS++))
fi

if [ -f "config/permissions-nodes.toml" ]; then
    log_success "✅ permissions-nodes.toml found"
else
    log_warn "⚠️  permissions-nodes.toml not found (optional)"
    ((WARNINGS++))
fi

log_info "=== 9. Besu Configuration ==="
# Check for Besu-specific configuration
BESU_CONFIG_FILES=(
    "config/besu-config.toml"
    "config/besu.toml"
    "helm/besu-network/templates/configmap.yaml"
)

for config_file in "${BESU_CONFIG_FILES[@]}"; do
    if [ -f "$config_file" ]; then
        log_success "✅ Found: ${config_file}"
        
        # Check for RPC configuration
        if grep -q "rpc-http" "$config_file" || grep -q "rpc-http-enabled" "$config_file"; then
            log_success "   ✅ RPC HTTP configuration found"
        fi
        
        # Check for P2P configuration
        if grep -q "p2p" "$config_file" || grep -q "discovery" "$config_file"; then
            log_success "   ✅ P2P configuration found"
        fi
    fi
done

log_info "=== 10. Consistency Checks ==="

# Check Chain ID consistency
CHAIN_IDS=()
if [ -f "config/genesis.json" ]; then
    GENESIS_CHAIN_ID=$(grep -oE '"chainId"[[:space:]]*:[[:space:]]*[0-9]+' config/genesis.json | grep -oE '[0-9]+' || echo "")
    if [ -n "$GENESIS_CHAIN_ID" ]; then
        CHAIN_IDS+=("genesis: $GENESIS_CHAIN_ID")
    fi
fi

if [ -f "helm/besu-network/values-validators.yaml" ]; then
    HELM_CHAIN_ID=$(grep -E "chainId|chain-id|CHAIN_ID" helm/besu-network/values-validators.yaml | grep -oE '[0-9]+' | head -1 || echo "")
    if [ -n "$HELM_CHAIN_ID" ]; then
        CHAIN_IDS+=("helm: $HELM_CHAIN_ID")
    fi
fi

if [ ${#CHAIN_IDS[@]} -gt 1 ]; then
    UNIQUE_CHAIN_IDS=$(printf '%s\n' "${CHAIN_IDS[@]}" | cut -d' ' -f2 | sort -u | wc -l)
    if [ "$UNIQUE_CHAIN_IDS" -eq 1 ]; then
        log_success "✅ Chain ID consistent across configurations"
    else
        log_error "❌ Chain ID mismatch detected:"
        for id in "${CHAIN_IDS[@]}"; do
            log_error "   - ${id}"
        done
        ((ERRORS++))
    fi
fi

log_info "=== 11. Missing Configuration Check ==="

# Check for missing critical files
MISSING_FILES=()

if [ ! -f "terraform/backend.tf" ] && [ ! -f "terraform/backend.tf.example" ]; then
    MISSING_FILES+=("terraform/backend.tf (Terraform backend configuration)")
fi

if [ ! -f "k8s/gateway/nginx-config.yaml" ]; then
    MISSING_FILES+=("k8s/gateway/nginx-config.yaml (API Gateway configuration)")
fi

if [ ! -f "monitoring/k8s/prometheus.yaml" ]; then
    MISSING_FILES+=("monitoring/k8s/prometheus.yaml (Prometheus configuration)")
fi

if [ ${#MISSING_FILES[@]} -gt 0 ]; then
    log_warn "⚠️  Missing optional configuration files:"
    for file in "${MISSING_FILES[@]}"; do
        log_warn "   - ${file}"
        ((WARNINGS++))
    done
else
    log_success "✅ All critical configuration files present"
fi

log_info "=== 12. Documentation ==="
check_file "docs/DEPLOYMENT_ORDER.md" "Deployment order documentation"
check_file "docs/DEPLOYMENT.md" "Deployment guide"
check_file "docs/ARCHITECTURE.md" "Architecture documentation"
check_file "docs/DEPLOYMENT_COMPLETE_GUIDE.md" "Complete deployment guide"

log_info "=== Summary ==="
log_success "Errors: ${ERRORS}"
log_warn "Warnings: ${WARNINGS}"

if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
    log_success "✅ All configurations validated successfully!"
    exit 0
elif [ $ERRORS -eq 0 ]; then
    log_warn "⚠️  Configuration validated with warnings"
    log_warn "   Review warnings above and address as needed"
    exit 0
else
    log_error "❌ Configuration validation failed"
    log_error "   Please fix ${ERRORS} error(s) before deployment"
    exit 1
fi
