#!/bin/bash
# error-handling.sh - Enhanced error monitoring for bash deployment scripts

# Error tracking variables
ERROR_LOG_FILE="${DEPLOY_DIR:-./deploy}/error.log"
ERROR_COUNT=0
LAST_ERROR=""
OPERATION_STACK=()

# Enhanced error reporting
function log_error() {
    local error_message="$1"
    local operation="${2:-Unknown}"
    local error_code="${3:-1}"
    local timestamp="$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")"
    
    ERROR_COUNT=$((ERROR_COUNT + 1))
    LAST_ERROR="$error_message"
    
    # Log to file
    echo "[$timestamp] ERROR [$operation] (code: $error_code): $error_message" >> "$ERROR_LOG_FILE"
    
    # Display formatted error
    echo -e "${RED}❌ [$operation] $error_message${NC}" >&2
    
    # Add context if available
    if [[ ${#OPERATION_STACK[@]} -gt 0 ]]; then
        echo -e "${WHITE}📍 Operation stack: ${OPERATION_STACK[*]}${NC}" >&2
    fi
    
    # Show error suggestions
    show_error_suggestions "$error_message" "$operation"
}

function show_error_suggestions() {
    local error_message="$1"
    local operation="$2"
    
    echo -e "\n${CYAN}💡 Troubleshooting suggestions:${NC}" >&2
    
    # AWS credential errors
    if [[ "$error_message" == *"credentials"* ]] || [[ "$error_message" == *"Unable to locate"* ]]; then
        echo -e "   • Check AWS credentials: ${YELLOW}aws sts get-caller-identity${NC}" >&2
        echo -e "   • Configure AWS: ${YELLOW}aws configure${NC}" >&2
        echo -e "   • Use CFN-Forge: ${YELLOW}cfn-forge config --aws${NC}" >&2
        
    # CloudFormation errors
    elif [[ "$error_message" == *"ValidationError"* ]] || [[ "$error_message" == *"template"* ]]; then
        echo -e "   • Validate template: ${YELLOW}aws cloudformation validate-template --template-body file://template.yaml${NC}" >&2
        echo -e "   • Check template syntax and required parameters" >&2
        
    # Permission errors
    elif [[ "$error_message" == *"AccessDenied"* ]] || [[ "$error_message" == *"not authorized"* ]]; then
        echo -e "   • Check IAM permissions for CloudFormation operations" >&2
        echo -e "   • Verify AWS profile has necessary access" >&2
        echo -e "   • Try using administrator credentials temporarily" >&2
        
    # Stack already exists
    elif [[ "$error_message" == *"already exists"* ]]; then
        echo -e "   • Delete existing stack: ${YELLOW}aws cloudformation delete-stack --stack-name \$STACK_NAME${NC}" >&2
        echo -e "   • Use update instead of create operation" >&2
        echo -e "   • Check stack status: ${YELLOW}aws cloudformation describe-stacks --stack-name \$STACK_NAME${NC}" >&2
        
    # Git errors
    elif [[ "$error_message" == *"git"* ]] || [[ "$operation" == *"Git"* ]]; then
        echo -e "   • Initialize git: ${YELLOW}git init${NC}" >&2
        echo -e "   • Check git status: ${YELLOW}git status${NC}" >&2
        echo -e "   • Commit changes: ${YELLOW}git add . && git commit -m \"Initial commit\"${NC}" >&2
        
    # File/directory errors
    elif [[ "$error_message" == *"No such file"* ]] || [[ "$error_message" == *"not found"* ]]; then
        echo -e "   • Check file paths in configuration" >&2
        echo -e "   • Verify template file exists: ${YELLOW}ls -la \$TEMPLATE_FILE${NC}" >&2
        echo -e "   • Check current directory: ${YELLOW}pwd${NC}" >&2
        
    # Network/timeout errors
    elif [[ "$error_message" == *"timeout"* ]] || [[ "$error_message" == *"network"* ]]; then
        echo -e "   • Check internet connectivity" >&2
        echo -e "   • Verify AWS endpoint accessibility" >&2
        echo -e "   • Try again in a few minutes" >&2
        
    # Rate limiting
    elif [[ "$error_message" == *"Throttling"* ]] || [[ "$error_message" == *"Rate exceeded"* ]]; then
        echo -e "   • Wait 30-60 seconds and retry" >&2
        echo -e "   • AWS is rate limiting requests" >&2
        
    # Generic suggestions
    else
        echo -e "   • Enable debug mode: ${YELLOW}DEBUG=1 cfn-forge deploy${NC}" >&2
        echo -e "   • Check AWS service status: https://status.aws.amazon.com/" >&2
        echo -e "   • Review error log: ${YELLOW}cat $ERROR_LOG_FILE${NC}" >&2
    fi
    
    echo >&2
}

# Operation tracking
function start_operation() {
    local operation="$1"
    OPERATION_STACK+=("$operation")
    
    if [[ "$CFN_FORGE_DEBUG" == "true" ]]; then
        echo -e "${WHITE}🔍 Starting: $operation${NC}" >&2
    fi
}

function end_operation() {
    local operation="$1"
    local success="${2:-true}"
    
    # Remove from stack
    if [[ ${#OPERATION_STACK[@]} -gt 0 ]]; then
        unset 'OPERATION_STACK[${#OPERATION_STACK[@]}-1]'
    fi
    
    if [[ "$CFN_FORGE_DEBUG" == "true" ]]; then
        if [[ "$success" == "true" ]]; then
            echo -e "${WHITE}✅ Completed: $operation${NC}" >&2
        else
            echo -e "${WHITE}❌ Failed: $operation${NC}" >&2
        fi
    fi
}

# Enhanced error handling for AWS CLI commands
function aws_with_error_handling() {
    local operation="$1"
    shift
    local aws_command="$*"
    
    start_operation "$operation"
    
    if [[ "$CFN_FORGE_DEBUG" == "true" ]]; then
        echo -e "${WHITE}🔍 AWS CLI: $aws_command${NC}" >&2
    fi
    
    local temp_error_file="/tmp/cfn-forge-aws-error-$$"
    
    if aws $aws_command 2>"$temp_error_file"; then
        end_operation "$operation" "true"
        rm -f "$temp_error_file"
        return 0
    else
        local exit_code=$?
        local error_output=""
        
        if [[ -f "$temp_error_file" ]]; then
            error_output="$(cat "$temp_error_file")"
            rm -f "$temp_error_file"
        fi
        
        log_error "AWS CLI command failed: $aws_command\nOutput: $error_output" "$operation" "$exit_code"
        end_operation "$operation" "false"
        
        return $exit_code
    fi
}

# Enhanced git error handling
function git_with_error_handling() {
    local operation="$1"
    shift
    local git_command="$*"
    
    start_operation "Git: $operation"
    
    if [[ "$CFN_FORGE_DEBUG" == "true" ]]; then
        echo -e "${WHITE}🔍 Git: $git_command${NC}" >&2
    fi
    
    local temp_error_file="/tmp/cfn-forge-git-error-$$"
    
    if git $git_command 2>"$temp_error_file"; then
        end_operation "Git: $operation" "true"
        rm -f "$temp_error_file"
        return 0
    else
        local exit_code=$?
        local error_output=""
        
        if [[ -f "$temp_error_file" ]]; then
            error_output="$(cat "$temp_error_file")"
            rm -f "$temp_error_file"
        fi
        
        log_error "Git command failed: $git_command\nOutput: $error_output" "Git: $operation" "$exit_code"
        end_operation "Git: $operation" "false"
        
        return $exit_code
    fi
}

# Validation with error handling
function validate_file_exists() {
    local file_path="$1"
    local description="${2:-File}"
    
    start_operation "Validate: $description"
    
    if [[ ! -f "$file_path" ]]; then
        log_error "$description not found: $file_path" "File Validation" "2"
        end_operation "Validate: $description" "false"
        return 1
    fi
    
    end_operation "Validate: $description" "true"
    return 0
}

function validate_directory_exists() {
    local dir_path="$1"
    local description="${2:-Directory}"
    
    start_operation "Validate: $description"
    
    if [[ ! -d "$dir_path" ]]; then
        log_error "$description not found: $dir_path" "Directory Validation" "2"
        end_operation "Validate: $description" "false"
        return 1
    fi
    
    end_operation "Validate: $description" "true"
    return 0
}

# Error recovery functions
function attempt_recovery() {
    local error_type="$1"
    local context="$2"
    
    echo -e "\n${YELLOW}🔄 Attempting automatic recovery for: $error_type${NC}" >&2
    
    case "$error_type" in
        "credentials")
            echo -e "${WHITE}• Checking for AWS credentials in multiple locations...${NC}" >&2
            # Try different credential sources
            if aws sts get-caller-identity --profile default >/dev/null 2>&1; then
                echo -e "${GREEN}✅ Found working credentials with default profile${NC}" >&2
                export AWS_PROFILE="default"
                return 0
            fi
            ;;
            
        "stack_exists")
            echo -e "${WHITE}• Checking if stack update is possible...${NC}" >&2
            local stack_status=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null)
            if [[ "$stack_status" == "CREATE_COMPLETE" ]] || [[ "$stack_status" == "UPDATE_COMPLETE" ]]; then
                echo -e "${GREEN}✅ Stack exists and is in updatable state${NC}" >&2
                echo -e "${CYAN}💡 Consider using UPDATE instead of CREATE${NC}" >&2
                return 0
            fi
            ;;
            
        "git_dirty")
            echo -e "${WHITE}• Checking if changes can be automatically committed...${NC}" >&2
            if git add . && git commit -m "Auto-commit before deployment" >/dev/null 2>&1; then
                echo -e "${GREEN}✅ Automatically committed pending changes${NC}" >&2
                return 0
            fi
            ;;
    esac
    
    echo -e "${RED}❌ Automatic recovery failed${NC}" >&2
    return 1
}

# Error summary report
function generate_error_report() {
    if [[ $ERROR_COUNT -eq 0 ]]; then
        echo -e "\n${GREEN}✅ No errors encountered during deployment${NC}"
        return 0
    fi
    
    echo -e "\n${RED}📋 Error Summary${NC}"
    echo -e "${RED}═══════════════${NC}"
    echo -e "Total errors: $ERROR_COUNT"
    echo -e "Last error: $LAST_ERROR"
    echo -e "Error log: $ERROR_LOG_FILE"
    
    if [[ -f "$ERROR_LOG_FILE" ]]; then
        echo -e "\n${YELLOW}Recent errors:${NC}"
        tail -5 "$ERROR_LOG_FILE" | while IFS= read -r line; do
            echo -e "  ${WHITE}$line${NC}"
        done
    fi
    
    echo -e "\n${CYAN}🔍 For detailed debugging:${NC}"
    echo -e "  • Set DEBUG=1 for verbose output"
    echo -e "  • Check error log: ${YELLOW}cat $ERROR_LOG_FILE${NC}"
    echo -e "  • Review AWS CloudFormation console"
    echo -e "  • Run: ${YELLOW}cfn-forge validate${NC}"
    
    return $ERROR_COUNT
}

# Cleanup on script exit
function cleanup_error_handling() {
    if [[ $ERROR_COUNT -gt 0 ]]; then
        generate_error_report
    fi
    
    # Clean up temporary files
    rm -f /tmp/cfn-forge-*-error-*
}

# Set up exit trap
trap cleanup_error_handling EXIT

# Export functions for use in other scripts
export -f log_error
export -f show_error_suggestions
export -f start_operation
export -f end_operation
export -f aws_with_error_handling
export -f git_with_error_handling
export -f validate_file_exists
export -f validate_directory_exists
export -f attempt_recovery
export -f generate_error_report