#!/bin/bash

# PropTrader Pro Test Runner Script
# This script runs all tests with proper configuration and reporting

set -e  # Exit on any error

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

# Configuration
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TEST_RESULTS_DIR="$PROJECT_DIR/storage/test-results"
COVERAGE_DIR="$PROJECT_DIR/storage/coverage"

# Functions
log() {
    echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}"
}

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

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

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

# Create necessary directories
setup_directories() {
    log "Setting up test directories..."
    
    mkdir -p "$TEST_RESULTS_DIR"
    mkdir -p "$COVERAGE_DIR"
    
    log "Test directories created"
}

# Check prerequisites
check_prerequisites() {
    log "Checking prerequisites..."
    
    # Check if composer is installed
    if ! command -v composer &> /dev/null; then
        error "Composer is not installed"
    fi
    
    # Check if phpunit is available
    if ! composer show phpunit/phpunit &> /dev/null; then
        warning "PHPUnit is not installed, installing..."
        composer require --dev phpunit/phpunit
    fi
    
    # Check if dusk is available for browser tests
    if ! composer show laravel/dusk &> /dev/null; then
        warning "Laravel Dusk is not installed, installing..."
        composer require --dev laravel/dusk
    fi
    
    log "Prerequisites check completed"
}

# Setup environment for testing
setup_test_environment() {
    log "Setting up test environment..."
    
    cd "$PROJECT_DIR"
    
    # Copy testing environment file
    if [[ ! -f ".env.testing" ]]; then
        cp .env .env.testing
    fi
    
    # Generate application key for testing
    php artisan key:generate --env=testing
    
    # Clear and cache config
    php artisan config:clear
    php artisan config:cache --env=testing
    
    # Run migrations for testing
    php artisan migrate:fresh --env=testing
    
    # Seed database for testing
    php artisan db:seed --env=testing
    
    log "Test environment setup completed"
}

# Run unit tests
run_unit_tests() {
    log "Running unit tests..."
    
    cd "$PROJECT_DIR"
    
    ./vendor/bin/phpunit \
        --testsuite=Unit \
        --configuration=phpunit.xml \
        --coverage-html="$COVERAGE_DIR/unit" \
        --coverage-clover="$TEST_RESULTS_DIR/unit-coverage.xml" \
        --log-junit="$TEST_RESULTS_DIR/unit-results.xml" \
        --colors=always \
        --verbose
    
    log "Unit tests completed"
}

# Run feature tests
run_feature_tests() {
    log "Running feature tests..."
    
    cd "$PROJECT_DIR"
    
    ./vendor/bin/phpunit \
        --testsuite=Feature \
        --configuration=phpunit.xml \
        --coverage-html="$COVERAGE_DIR/feature" \
        --coverage-clover="$TEST_RESULTS_DIR/feature-coverage.xml" \
        --log-junit="$TEST_RESULTS_DIR/feature-results.xml" \
        --colors=always \
        --verbose
    
    log "Feature tests completed"
}

# Run browser tests
run_browser_tests() {
    log "Running browser tests..."
    
    cd "$PROJECT_DIR"
    
    # Check if Chrome driver is available
    if ! command -v chromedriver &> /dev/null; then
        warning "ChromeDriver is not installed, installing..."
        # Install ChromeDriver (Linux)
        if [[ "$OSTYPE" == "linux-gnu"* ]]; then
            wget -O /tmp/chromedriver.zip https://chromedriver.storage.googleapis.com/LATEST_RELEASE/chromedriver_linux64.zip
            unzip /tmp/chromedriver.zip -d /usr/local/bin/
            chmod +x /usr/local/bin/chromedriver
        fi
    fi
    
    # Start Chrome driver
    chromedriver --port=9515 &
    CHROME_DRIVER_PID=$!
    
    # Wait for Chrome driver to start
    sleep 5
    
    # Run Dusk tests
    php artisan dusk \
        --env=testing \
        --log-junit="$TEST_RESULTS_DIR/browser-results.xml"
    
    # Stop Chrome driver
    kill $CHROME_DRIVER_PID
    
    log "Browser tests completed"
}

# Run all tests
run_all_tests() {
    log "Running all tests..."
    
    setup_directories
    check_prerequisites
    setup_test_environment
    
    run_unit_tests
    run_feature_tests
    run_browser_tests
    
    log "All tests completed"
}

# Generate test report
generate_test_report() {
    log "Generating test report..."
    
    local report_file="$TEST_RESULTS_DIR/test-report-$(date +%Y%m%d_%H%M%S).html"
    
    cat > "$report_file" << EOF
<!DOCTYPE html>
<html>
<head>
    <title>PropTrader Pro Test Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .header { background: #f5f5f5; padding: 20px; border-radius: 5px; }
        .section { margin: 20px 0; }
        .test-suite { background: #f9f9f9; padding: 15px; margin: 10px 0; border-radius: 5px; }
        .success { color: #28a745; }
        .error { color: #dc3545; }
        .warning { color: #ffc107; }
        table { width: 100%; border-collapse: collapse; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .progress-bar { width: 100%; background-color: #f0f0f0; border-radius: 5px; }
        .progress-fill { height: 20px; background-color: #28a745; border-radius: 5px; }
    </style>
</head>
<body>
    <div class="header">
        <h1>PropTrader Pro Test Report</h1>
        <p>Generated on: $(date)</p>
        <p>Environment: Testing</p>
    </div>
    
    <div class="section">
        <h2>Test Summary</h2>
        <table>
            <tr>
                <th>Test Suite</th>
                <th>Tests Run</th>
                <th>Passed</th>
                <th>Failed</th>
                <th>Skipped</th>
                <th>Time</th>
                <th>Coverage</th>
            </tr>
EOF

    # Parse test results and add to report
    for suite in unit feature browser; do
        local results_file="$TEST_RESULTS_DIR/${suite}-results.xml"
        if [[ -f "$results_file" ]]; then
            local tests=$(grep -o 'tests="[0-9]*"' "$results_file" | grep -o '[0-9]*')
            local failures=$(grep -o 'failures="[0-9]*"' "$results_file" | grep -o '[0-9]*')
            local skipped=$(grep -o 'skipped="[0-9]*"' "$results_file" | grep -o '[0-9]*')
            local time=$(grep -o 'time="[0-9.]*"' "$results_file" | grep -o '[0-9.]*')
            local passed=$((tests - failures))
            
            cat >> "$report_file" << EOF
            <tr>
                <td>${suite^}</td>
                <td>$tests</td>
                <td class="success">$passed</td>
                <td class="error">$failures</td>
                <td class="warning">$skipped</td>
                <td>${time}s</td>
                <td><a href="coverage/${suite}/index.html">View Coverage</a></td>
            </tr>
EOF
        fi
    done

    cat >> "$report_file" << EOF
        </table>
    </div>
    
    <div class="section">
        <h2>Coverage Reports</h2>
        <ul>
            <li><a href="coverage/unit/index.html">Unit Test Coverage</a></li>
            <li><a href="coverage/feature/index.html">Feature Test Coverage</a></li>
        </ul>
    </div>
    
    <div class="section">
        <h2>Test Results</h2>
        <ul>
            <li><a href="unit-results.xml">Unit Test Results (XML)</a></li>
            <li><a href="feature-results.xml">Feature Test Results (XML)</a></li>
            <li><a href="browser-results.xml">Browser Test Results (XML)</a></li>
        </ul>
    </div>
</body>
</html>
EOF

    log "Test report generated: $report_file"
}

# Clean up test artifacts
cleanup() {
    log "Cleaning up test artifacts..."
    
    cd "$PROJECT_DIR"
    
    # Reset database
    php artisan migrate:rollback --env=testing
    
    # Clear cache
    php artisan cache:clear --env=testing
    
    # Remove temporary files
    rm -f .env.testing
    
    log "Cleanup completed"
}

# Send notification
send_notification() {
    local status=$1
    local message=$2
    
    if [[ -n "$SLACK_WEBHOOK_URL" ]]; then
        local color="good"
        if [[ "$status" == "failed" ]]; then
            color="danger"
        fi
        
        curl -X POST -H 'Content-type: application/json' \
            --data "{\"text\":\"$message\", \"color\":\"$color\"}" \
            "$SLACK_WEBHOOK_URL"
    fi
    
    if [[ -n "$NOTIFICATION_EMAIL" ]]; then
        echo "$message" | mail -s "PropTrader Pro Test Results: $status" "$NOTIFICATION_EMAIL"
    fi
}

# Main execution
main() {
    local test_type=${1:-all}
    local cleanup_after=${2:-true}
    
    log "Starting PropTrader Pro test suite..."
    
    case $test_type in
        "unit")
            setup_directories
            check_prerequisites
            setup_test_environment
            run_unit_tests
            ;;
        "feature")
            setup_directories
            check_prerequisites
            setup_test_environment
            run_feature_tests
            ;;
        "browser")
            setup_directories
            check_prerequisites
            setup_test_environment
            run_browser_tests
            ;;
        "all")
            run_all_tests
            ;;
        *)
            echo "Usage: $0 [unit|feature|browser|all] [cleanup|no-cleanup]"
            exit 1
            ;;
    esac
    
    generate_test_report
    
    if [[ "$cleanup_after" == "true" ]]; then
        cleanup
    fi
    
    log "Test suite completed successfully!"
    send_notification "success" "PropTrader Pro tests completed successfully"
}

# Handle script interruption
trap 'cleanup; exit 1' INT TERM

# Check for command line arguments
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
    echo "PropTrader Pro Test Runner"
    echo "Usage: $0 [test_type] [cleanup_option]"
    echo ""
    echo "Test types:"
    echo "  unit     - Run unit tests only"
    echo "  feature  - Run feature tests only"
    echo "  browser  - Run browser tests only"
    echo "  all      - Run all tests (default)"
    echo ""
    echo "Cleanup options:"
    echo "  cleanup  - Clean up after tests (default)"
    echo "  no-cleanup - Leave test artifacts"
    echo ""
    echo "Examples:"
    echo "  $0                    # Run all tests and cleanup"
    echo "  $0 unit               # Run unit tests only"
    echo "  $0 feature no-cleanup # Run feature tests without cleanup"
    exit 0
fi

# Run main function
main "$@"
