#!/usr/bin/env bash
# Validation functions for scripts
# Usage: source "$SCRIPT_DIR/lib/common/validation.sh"

# Source colors and logging if not already sourced
[ -z "${RED:-}" ] && source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/colors.sh"
[ -z "$(type -t log_error)" ] && source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/logging.sh"

# Validate required environment variable
validate_required() {
    local var_name="$1"
    local var_value="${!var_name:-}"
    
    if [ -z "$var_value" ]; then
        log_error "$var_name is required but not set"
        return 1
    fi
    return 0
}

# Validate file exists
validate_file_exists() {
    local file_path="$1"
    local description="${2:-File}"
    
    if [ ! -f "$file_path" ]; then
        log_error "$description not found: $file_path"
        return 1
    fi
    return 0
}

# Validate directory exists
validate_directory_exists() {
    local dir_path="$1"
    local description="${2:-Directory}"
    
    if [ ! -d "$dir_path" ]; then
        log_error "$description not found: $dir_path"
        return 1
    fi
    return 0
}

# Validate JSON file
validate_json() {
    local json_file="$1"
    
    if ! python3 -m json.tool "$json_file" >/dev/null 2>&1; then
        log_error "Invalid JSON file: $json_file"
        return 1
    fi
    return 0
}

# Validate YAML file
validate_yaml() {
    local yaml_file="$1"
    
    if ! command -v yamllint &>/dev/null; then
        log_warn "yamllint not installed, skipping YAML validation"
        return 0
    fi
    
    if ! yamllint "$yaml_file" >/dev/null 2>&1; then
        log_error "Invalid YAML file: $yaml_file"
        return 1
    fi
    return 0
}

# Validate TOML file
validate_toml() {
    local toml_file="$1"
    
    if ! python3 -c "import tomllib; open('$toml_file', 'rb').read()" 2>/dev/null; then
        log_error "Invalid TOML file: $toml_file"
        return 1
    fi
    return 0
}

# Validate URL format
validate_url() {
    local url="$1"
    
    if [[ ! "$url" =~ ^https?:// ]]; then
        log_error "Invalid URL format: $url"
        return 1
    fi
    return 0
}

# Validate IP address
validate_ip() {
    local ip="$1"
    
    if [[ ! "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        log_error "Invalid IP address format: $ip"
        return 1
    fi
    
    # Check each octet is 0-255
    IFS='.' read -ra ADDR <<< "$ip"
    for i in "${ADDR[@]}"; do
        if [ "$i" -gt 255 ] || [ "$i" -lt 0 ]; then
            log_error "Invalid IP address: $ip (octet out of range)"
            return 1
        fi
    done
    return 0
}

# Validate port number
validate_port() {
    local port="$1"
    
    if [[ ! "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then
        log_error "Invalid port number: $port (must be 1-65535)"
        return 1
    fi
    return 0
}

# Validate Ethereum address
validate_eth_address() {
    local address="$1"
    
    if [[ ! "$address" =~ ^0x[0-9a-fA-F]{40}$ ]]; then
        log_error "Invalid Ethereum address format: $address"
        return 1
    fi
    return 0
}

# Validate chain ID
validate_chain_id() {
    local chain_id="$1"
    
    if [[ ! "$chain_id" =~ ^[0-9]+$ ]] || [ "$chain_id" -lt 1 ]; then
        log_error "Invalid chain ID: $chain_id"
        return 1
    fi
    return 0
}

# Validate non-empty string
validate_non_empty() {
    local value="$1"
    local name="${2:-Value}"
    
    if [ -z "$value" ]; then
        log_error "$name cannot be empty"
        return 1
    fi
    return 0
}

# Validate numeric value
validate_numeric() {
    local value="$1"
    local name="${2:-Value}"
    
    if [[ ! "$value" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
        log_error "$name must be numeric: $value"
        return 1
    fi
    return 0
}

# Validate positive number
validate_positive() {
    local value="$1"
    local name="${2:-Value}"
    
    if ! validate_numeric "$value" "$name"; then
        return 1
    fi
    
    if (( $(echo "$value <= 0" | bc -l) )); then
        log_error "$name must be positive: $value"
        return 1
    fi
    return 0
}

# Validate command exists
validate_command() {
    local cmd="$1"
    
    if ! command -v "$cmd" &>/dev/null; then
        log_error "Command not found: $cmd"
        return 1
    fi
    return 0
}

# Validate multiple requirements
validate_all() {
    local failed=0
    
    while [ $# -gt 0 ]; do
        if ! "$@"; then
            failed=1
        fi
        shift
    done
    
    return $failed
}

