#!/bin/bash
# Integration Tests for RootManage-Module-Model
# Tests the entire usr directory functionality

set -e

# Test configuration
TEST_DIR="/tmp/pyrmm_test"
TEST_MODULE_DIR="$TEST_DIR/test_module"
USR_DIR="$(dirname "$(dirname "$(realpath "$0")")")"

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

# Test counters
TOTAL_TESTS=0
PASSED_TESTS=0
FAILED_TESTS=0

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

log_success() {
    echo -e "${GREEN}[✓]${NC} $1"
    ((PASSED_TESTS++))
}

log_error() {
    echo -e "${RED}[✗]${NC} $1"
    ((FAILED_TESTS++))
}

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

run_test() {
    local test_name="$1"
    local test_function="$2"
    
    log_info "Running test: $test_name"
    ((TOTAL_TESTS++))
    
    if $test_function; then
        log_success "Test passed: $test_name"
    else
        log_error "Test failed: $test_name"
    fi
    echo ""
}

# Setup test environment
setup_test_environment() {
    log_info "Setting up test environment"
    
    # Clean up any existing test directory
    rm -rf "$TEST_DIR"
    mkdir -p "$TEST_DIR"
    mkdir -p "$TEST_MODULE_DIR"
    
    # Copy usr directory to test location for isolated testing
    cp -r "$USR_DIR" "$TEST_DIR/usr"
    
    # Make scripts executable
    chmod +x "$TEST_DIR/usr/bin/"*
    
    # Add usr/bin to PATH for testing
    export PATH="$TEST_DIR/usr/bin:$PATH"
    
    log_success "Test environment setup complete"
}

# Cleanup test environment
cleanup_test_environment() {
    log_info "Cleaning up test environment"
    rm -rf "$TEST_DIR"
    log_success "Test environment cleaned up"
}

# Test 1: Basic tool availability
test_tool_availability() {
    local tools=(
        "module-builder"
        "module-packager" 
        "module-validator"
        "module-security"
        "config-manager"
    )
    
    for tool in "${tools[@]}"; do
        if command -v "$tool" >/dev/null 2>&1; then
            log_success "Tool available: $tool"
        else
            log_error "Tool not available: $tool"
            return 1
        fi
    done
    
    return 0
}

# Test 2: Module builder functionality
test_module_builder() {
    local test_module="$TEST_MODULE_DIR/basic_test"
    
    # Test module creation
    if module-builder create \
        --id "test_module" \
        --name "Test Module" \
        --author "TestSuite" \
        --description "Integration test module" \
        --template basic \
        --output "$test_module" >/dev/null 2>&1; then
        log_success "Module created with module-builder"
    else
        log_error "Failed to create module with module-builder"
        return 1
    fi
    
    # Verify created files
    local required_files=("module.prop" "customize.sh")
    for file in "${required_files[@]}"; do
        if [[ -f "$test_module/$file" ]]; then
            log_success "Required file created: $file"
        else
            log_error "Required file missing: $file"
            return 1
        fi
    done
    
    return 0
}

# Test 3: Module validator functionality  
test_module_validator() {
    local test_module="$TEST_MODULE_DIR/basic_test"
    
    # Ensure test module exists from previous test
    if [[ ! -d "$test_module" ]]; then
        log_error "Test module directory not found for validation test"
        return 1
    fi
    
    # Run validator
    if module-validator "$test_module" >/dev/null 2>&1; then
        log_success "Module validation passed"
    else
        log_error "Module validation failed"
        return 1
    fi
    
    # Test verbose mode
    if module-validator -v "$test_module" >/dev/null 2>&1; then
        log_success "Module validation (verbose) passed"
    else
        log_error "Module validation (verbose) failed"
        return 1
    fi
    
    return 0
}

# Test 4: Configuration manager functionality
test_config_manager() {
    local config_file="$TEST_DIR/test_config.ini"
    
    # Create test configuration
    cat > "$config_file" << 'EOF'
[test_section]
test_key=test_value
numeric_key=123
boolean_key=true

[another_section]
another_key=another_value
EOF
    
    # Test reading configuration
    local value
    if value=$(config-manager get test_section.test_key "$config_file" 2>/dev/null); then
        if [[ "$value" == "test_value" ]]; then
            log_success "Config reading works correctly"
        else
            log_error "Config reading returned wrong value: $value"
            return 1
        fi
    else
        log_error "Failed to read configuration"
        return 1
    fi
    
    # Test setting configuration
    if config-manager set test_section.new_key "new_value" "$config_file" >/dev/null 2>&1; then
        log_success "Config setting works correctly"
    else
        log_error "Failed to set configuration"
        return 1
    fi
    
    # Verify the set value
    if value=$(config-manager get test_section.new_key "$config_file" 2>/dev/null); then
        if [[ "$value" == "new_value" ]]; then
            log_success "Config verification passed"
        else
            log_error "Config verification failed: $value"
            return 1
        fi
    else
        log_error "Failed to verify set configuration"
        return 1
    fi
    
    return 0
}

# Test 5: Template system functionality
test_template_system() {
    local templates_dir="$TEST_DIR/usr/share/templates"
    
    # Check template files exist
    local templates=(
        "module.prop"
        "customize.sh.template"
        "audio-enhancement.prop.template"
        "performance-optimization.prop.template"
    )
    
    for template in "${templates[@]}"; do
        if [[ -f "$templates_dir/$template" ]]; then
            log_success "Template exists: $template"
        else
            log_error "Template missing: $template"
            return 1
        fi
    done
    
    # Test template variable substitution (if module-builder supports it)
    local test_output="$TEST_DIR/test_prop_output"
    if cp "$templates_dir/module.prop" "$test_output"; then
        # Simple variable substitution test
        sed -i 's/${MODULE_ID}/test_substitution/g' "$test_output"
        
        if grep -q "test_substitution" "$test_output"; then
            log_success "Template variable substitution works"
        else
            log_error "Template variable substitution failed"
            return 1
        fi
    else
        log_error "Failed to copy template for testing"
        return 1
    fi
    
    return 0
}

# Test 6: Example modules integrity
test_example_modules() {
    local examples_dir="$TEST_DIR/usr/share/examples"
    
    # Check example modules exist
    local examples=("basic-module" "webui-module" "service-module" "replacement-module")
    
    for example in "${examples[@]}"; do
        if [[ -d "$examples_dir/$example" ]]; then
            log_success "Example module exists: $example"
            
            # Check required files
            if [[ -f "$examples_dir/$example/module.prop" ]]; then
                log_success "Example $example has module.prop"
            else
                log_error "Example $example missing module.prop"
                return 1
            fi
            
            if [[ -f "$examples_dir/$example/README.md" ]]; then
                log_success "Example $example has README.md"
            else
                log_warning "Example $example missing README.md"
            fi
            
        else
            log_error "Example module missing: $example"
            return 1
        fi
    done
    
    return 0
}

# Test 7: Library functions
test_library_functions() {
    local lib_dir="$TEST_DIR/usr/lib"
    
    # Check library files exist
    local libraries=("common-functions.sh" "module-manager.sh" "webui-helpers.sh")
    
    for lib in "${libraries[@]}"; do
        if [[ -f "$lib_dir/$lib" ]]; then
            log_success "Library exists: $lib"
            
            # Test basic syntax
            if bash -n "$lib_dir/$lib" 2>/dev/null; then
                log_success "Library syntax OK: $lib"
            else
                log_error "Library syntax error: $lib"
                return 1
            fi
        else
            log_error "Library missing: $lib"
            return 1
        fi
    done
    
    return 0
}

# Test 8: Documentation integrity
test_documentation() {
    local doc_dir="$TEST_DIR/usr/share/doc"
    local man_dir="$TEST_DIR/usr/share/man/man1"
    
    # Check documentation files
    local docs=("api-reference.md")
    for doc in "${docs[@]}"; do
        if [[ -f "$doc_dir/$doc" ]]; then
            log_success "Documentation exists: $doc"
        else
            log_error "Documentation missing: $doc"
            return 1
        fi
    done
    
    # Check man pages
    local manpages=("module-builder.1" "module-packager.1")
    for manpage in "${manpages[@]}"; do
        if [[ -f "$man_dir/$manpage" ]]; then
            log_success "Man page exists: $manpage"
        else
            log_error "Man page missing: $manpage"
            return 1
        fi
    done
    
    return 0
}

# Test 9: Module security functionality
test_module_security() {
    local test_key_dir="$TEST_DIR/test_keys"
    mkdir -p "$test_key_dir"
    
    # Test key generation
    if module-security generate-keys \
        --output "$test_key_dir" \
        --keysize 2048 >/dev/null 2>&1; then
        log_success "Security key generation works"
    else
        log_error "Security key generation failed"
        return 1
    fi
    
    # Check generated files
    if [[ -f "$test_key_dir/private.pem" ]] && [[ -f "$test_key_dir/public.pem" ]]; then
        log_success "Security keys generated correctly"
    else
        log_error "Security key files not found"
        return 1
    fi
    
    return 0
}

# Test 10: Cross-tool integration
test_integration() {
    local integration_module="$TEST_MODULE_DIR/integration_test"
    
    # Create module with module-builder
    if ! module-builder create \
        --id "integration_test" \
        --name "Integration Test Module" \
        --author "TestSuite" \
        --description "Cross-tool integration test" \
        --template basic \
        --output "$integration_module" >/dev/null 2>&1; then
        log_error "Failed to create integration test module"
        return 1
    fi
    
    # Validate with module-validator
    if ! module-validator "$integration_module" >/dev/null 2>&1; then
        log_error "Integration module failed validation"
        return 1
    fi
    
    # Package with module-packager (if available)
    if command -v module-packager >/dev/null 2>&1; then
        local package_output="$TEST_DIR/integration_test.zip"
        if module-packager "$integration_module" "$package_output" >/dev/null 2>&1; then
            if [[ -f "$package_output" ]]; then
                log_success "Module packaging integration works"
            else
                log_error "Package file not created"
                return 1
            fi
        else
            log_error "Module packaging failed"
            return 1
        fi
    else
        log_warning "Module packager not available for integration test"
    fi
    
    log_success "Cross-tool integration test passed"
    return 0
}

# Generate test report
generate_test_report() {
    echo ""
    echo "==================== TEST REPORT ===================="
    echo "Test Run: $(date)"
    echo "Test Directory: $TEST_DIR"
    echo ""
    echo "Summary:"
    echo "  Total Tests: $TOTAL_TESTS"
    echo "  Passed: $PASSED_TESTS"  
    echo "  Failed: $FAILED_TESTS"
    echo ""
    
    local success_rate
    if [[ "$TOTAL_TESTS" -gt 0 ]]; then
        success_rate=$((PASSED_TESTS * 100 / TOTAL_TESTS))
    else
        success_rate=0
    fi
    
    echo "Success Rate: $success_rate%"
    echo ""
    
    if [[ "$FAILED_TESTS" -eq 0 ]]; then
        echo -e "${GREEN}✓ All tests PASSED${NC}"
    else
        echo -e "${RED}✗ $FAILED_TESTS tests FAILED${NC}"
    fi
    
    echo "======================================================"
}

# Main test execution
main() {
    echo "RootManage-Module-Model Integration Test Suite"
    echo "=============================================="
    echo ""
    
    # Setup
    setup_test_environment
    
    # Run all tests
    run_test "Tool Availability" test_tool_availability
    run_test "Module Builder" test_module_builder
    run_test "Module Validator" test_module_validator
    run_test "Configuration Manager" test_config_manager
    run_test "Template System" test_template_system
    run_test "Example Modules" test_example_modules
    run_test "Library Functions" test_library_functions
    run_test "Documentation" test_documentation
    run_test "Module Security" test_module_security
    run_test "Cross-tool Integration" test_integration
    
    # Generate report
    generate_test_report
    
    # Cleanup
    cleanup_test_environment
    
    # Exit with appropriate code
    if [[ "$FAILED_TESTS" -eq 0 ]]; then
        exit 0
    else
        exit 1
    fi
}

# Run main function
main "$@"
