#!/bin/bash

# Configuration Test Script for Rustelo
# Tests the configuration building and validation system
# Usage: ./test-config.sh

set -e

# Script configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_DIR="$(dirname "$SCRIPT_DIR")"
PROJECT_ROOT="$(dirname "$CONFIG_DIR")"
TEST_OUTPUT_DIR="$CONFIG_DIR/test_outputs"
ENVIRONMENTS=("dev" "prod" "example")

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
NC='\033[0m' # No Color

# Test counters
TESTS_PASSED=0
TESTS_FAILED=0
TESTS_TOTAL=0

# Logging functions
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_test() {
    echo -e "${PURPLE}[TEST]${NC} $1"
}

# Test result functions
test_passed() {
    local test_name="$1"
    TESTS_PASSED=$((TESTS_PASSED + 1))
    TESTS_TOTAL=$((TESTS_TOTAL + 1))
    log_success "✓ $test_name"
}

test_failed() {
    local test_name="$1"
    local error_msg="$2"
    TESTS_FAILED=$((TESTS_FAILED + 1))
    TESTS_TOTAL=$((TESTS_TOTAL + 1))
    log_error "✗ $test_name"
    if [ -n "$error_msg" ]; then
        log_error "  Error: $error_msg"
    fi
}

# Setup test environment
setup_test_environment() {
    log_info "Setting up test environment..."

    # Create test output directory
    rm -rf "$TEST_OUTPUT_DIR"
    mkdir -p "$TEST_OUTPUT_DIR"

    # Check if required scripts exist
    if [ ! -f "$SCRIPT_DIR/build-config.sh" ]; then
        log_error "build-config.sh not found"
        exit 1
    fi

    if [ ! -f "$SCRIPT_DIR/manage-config.sh" ]; then
        log_error "manage-config.sh not found"
        exit 1
    fi

    # Check if scripts are executable
    if [ ! -x "$SCRIPT_DIR/build-config.sh" ]; then
        chmod +x "$SCRIPT_DIR/build-config.sh"
    fi

    if [ ! -x "$SCRIPT_DIR/manage-config.sh" ]; then
        chmod +x "$SCRIPT_DIR/manage-config.sh"
    fi

    log_success "Test environment setup complete"
}

# Test configuration building
test_build_configurations() {
    log_info "Testing configuration building..."

    for env in "${ENVIRONMENTS[@]}"; do
        log_test "Building configuration for $env environment"

        local output_file="$TEST_OUTPUT_DIR/config_${env}_test.toml"

        if "$SCRIPT_DIR/build-config.sh" "$env" "$output_file" > /dev/null 2>&1; then
            if [ -f "$output_file" ]; then
                test_passed "Build $env configuration"
            else
                test_failed "Build $env configuration" "Output file not created"
            fi
        else
            test_failed "Build $env configuration" "Build script failed"
        fi
    done
}

# Test configuration validation
test_validate_configurations() {
    log_info "Testing configuration validation..."

    for env in "${ENVIRONMENTS[@]}"; do
        log_test "Validating configuration for $env environment"

        if "$SCRIPT_DIR/manage-config.sh" validate "$env" > /dev/null 2>&1; then
            test_passed "Validate $env configuration"
        else
            test_failed "Validate $env configuration" "Validation failed"
        fi
    done
}

# Test configuration file structure
test_configuration_structure() {
    log_info "Testing configuration file structure..."

    for env in "${ENVIRONMENTS[@]}"; do
        log_test "Checking structure of $env configuration"

        local config_file="$TEST_OUTPUT_DIR/config_${env}_test.toml"

        if [ ! -f "$config_file" ]; then
            test_failed "Check $env structure" "Configuration file not found"
            continue
        fi

        # Check for required sections
        local required_sections=("server" "database" "app" "build_info")
        local missing_sections=()

        for section in "${required_sections[@]}"; do
            if ! grep -q "^\[${section}\]" "$config_file"; then
                missing_sections+=("$section")
            fi
        done

        if [ ${#missing_sections[@]} -eq 0 ]; then
            test_passed "Check $env structure"
        else
            test_failed "Check $env structure" "Missing sections: ${missing_sections[*]}"
        fi
    done
}

# Test feature configurations
test_feature_configurations() {
    log_info "Testing feature configurations..."

    local features_dir="$CONFIG_DIR/features"

    if [ ! -d "$features_dir" ]; then
        test_failed "Check features directory" "Features directory not found"
        return
    fi

    # Check if features directory has subdirectories
    local feature_count=0
    for feature_dir in "$features_dir"/*; do
        if [ -d "$feature_dir" ]; then
            feature_count=$((feature_count + 1))
            local feature_name=$(basename "$feature_dir")
            log_test "Checking feature: $feature_name"

            # Check if feature has environment configs
            local env_configs=0
            for env in "${ENVIRONMENTS[@]}"; do
                if [ -f "$feature_dir/$env.toml" ]; then
                    env_configs=$((env_configs + 1))
                fi
            done

            if [ $env_configs -gt 0 ]; then
                test_passed "Feature $feature_name has environment configs"
            else
                test_failed "Feature $feature_name has environment configs" "No environment configs found"
            fi
        fi
    done

    if [ $feature_count -gt 0 ]; then
        test_passed "Features directory structure"
    else
        test_failed "Features directory structure" "No features found"
    fi
}

# Test base configurations
test_base_configurations() {
    log_info "Testing base configurations..."

    local base_dir="$CONFIG_DIR/base"

    if [ ! -d "$base_dir" ]; then
        test_failed "Check base directory" "Base directory not found"
        return
    fi

    for env in "${ENVIRONMENTS[@]}"; do
        log_test "Checking base configuration for $env"

        local base_file="$base_dir/$env.toml"

        if [ -f "$base_file" ]; then
            # Check if file is valid TOML (basic check)
            if grep -q "^\[.*\]" "$base_file"; then
                test_passed "Base $env configuration exists and has sections"
            else
                test_failed "Base $env configuration exists and has sections" "No TOML sections found"
            fi
        else
            test_failed "Base $env configuration exists" "File not found"
        fi
    done
}

# Test management script commands
test_management_commands() {
    log_info "Testing management script commands..."

    # Test list-features command
    log_test "Testing list-features command"
    if "$SCRIPT_DIR/manage-config.sh" list-features > /dev/null 2>&1; then
        test_passed "list-features command"
    else
        test_failed "list-features command" "Command failed"
    fi

    # Test list-environments command
    log_test "Testing list-environments command"
    if "$SCRIPT_DIR/manage-config.sh" list-environments > /dev/null 2>&1; then
        test_passed "list-environments command"
    else
        test_failed "list-environments command" "Command failed"
    fi

    # Test status command
    log_test "Testing status command"
    if "$SCRIPT_DIR/manage-config.sh" status > /dev/null 2>&1; then
        test_passed "status command"
    else
        test_failed "status command" "Command failed"
    fi
}

# Test Python configuration builder (if available)
test_python_builder() {
    log_info "Testing shell configuration builder (Python builder removed)..."
    test_skipped "Python builder" "Python builder has been removed from the project"
}

# Test configuration comparison
test_configuration_comparison() {
    log_info "Testing configuration comparison..."

    log_test "Testing configuration diff between dev and prod"
    if "$SCRIPT_DIR/manage-config.sh" diff dev prod > /dev/null 2>&1; then
        test_passed "Configuration diff"
    else
        test_failed "Configuration diff" "Diff command failed"
    fi
}

# Test backup and restore functionality
test_backup_restore() {
    log_info "Testing backup and restore functionality..."

    # Create a test config file
    local test_config="$TEST_OUTPUT_DIR/test_config.toml"
    echo "[test]" > "$test_config"
    echo "value = \"test\"" >> "$test_config"

    # Change to test directory
    cd "$TEST_OUTPUT_DIR"
    cp "$test_config" "config.toml"

    log_test "Testing backup creation"
    if "$SCRIPT_DIR/manage-config.sh" backup dev > /dev/null 2>&1; then
        test_passed "Backup creation"
    else
        test_failed "Backup creation" "Backup command failed"
    fi

    # Return to original directory
    cd - > /dev/null
}

# Test error handling
test_error_handling() {
    log_info "Testing error handling..."

    # Test invalid environment
    log_test "Testing invalid environment handling"
    if ! "$SCRIPT_DIR/build-config.sh" "invalid_env" "/tmp/test.toml" > /dev/null 2>&1; then
        test_passed "Invalid environment handling"
    else
        test_failed "Invalid environment handling" "Should have failed with invalid environment"
    fi

    # Test missing base config
    log_test "Testing missing base config handling"
    local backup_base="$CONFIG_DIR/base/dev.toml.backup"
    if [ -f "$CONFIG_DIR/base/dev.toml" ]; then
        mv "$CONFIG_DIR/base/dev.toml" "$backup_base"

        if ! "$SCRIPT_DIR/build-config.sh" "dev" "/tmp/test.toml" > /dev/null 2>&1; then
            test_passed "Missing base config handling"
        else
            test_failed "Missing base config handling" "Should have failed with missing base config"
        fi

        # Restore backup
        mv "$backup_base" "$CONFIG_DIR/base/dev.toml"
    else
        test_failed "Missing base config handling" "Base config already missing"
    fi
}

# Cleanup test environment
cleanup_test_environment() {
    log_info "Cleaning up test environment..."

    # Remove test output directory
    if [ -d "$TEST_OUTPUT_DIR" ]; then
        rm -rf "$TEST_OUTPUT_DIR"
    fi

    log_success "Test environment cleanup complete"
}

# Show test summary
show_test_summary() {
    echo ""
    echo "========================================"
    echo "Configuration Test Summary"
    echo "========================================"
    echo "Total Tests: $TESTS_TOTAL"
    echo "Passed: $TESTS_PASSED"
    echo "Failed: $TESTS_FAILED"

    if [ $TESTS_FAILED -eq 0 ]; then
        log_success "All tests passed! ✓"
        echo ""
        echo "The configuration system is working correctly."
    else
        log_error "Some tests failed! ✗"
        echo ""
        echo "Please review the failed tests and fix any issues."
        exit 1
    fi
}

# Main function
main() {
    echo "========================================"
    echo "Rustelo Configuration System Test Suite"
    echo "========================================"
    echo ""

    # Check if we're in the right directory
    if [ ! -d "$CONFIG_DIR" ]; then
        log_error "Configuration directory not found: $CONFIG_DIR"
        exit 1
    fi

    # Run tests
    setup_test_environment
    test_base_configurations
    test_feature_configurations
    test_build_configurations
    test_validate_configurations
    test_configuration_structure
    test_management_commands
    test_python_builder
    test_configuration_comparison
    test_backup_restore
    test_error_handling
    cleanup_test_environment
    show_test_summary
}

# Run main function
main "$@"
