#!/bin/bash
# optimize-tests.sh - Script to optimize test execution and performance
# Usage: ./bin/optimize-tests.sh [analyze|fix|profile] [--verbose]

set -e

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

# Default settings
ACTION=""
VERBOSE=false
CURRENT_DATE=$(date +"%Y-%m-%d")

# Parse arguments
for arg in "$@"; do
  case $arg in
    analyze|fix|profile)
      ACTION="$arg"
      shift
      ;;
    --verbose)
      VERBOSE=true
      shift
      ;;
  esac
done

# Check if action is provided
if [ -z "$ACTION" ]; then
  echo -e "${RED}Error: No action specified. Use: analyze, fix, or profile${NC}"
  exit 1
fi

echo -e "${GREEN}=== Test Optimization - ${ACTION} ===${NC}"

# Check if we're in the right directory
if [ ! -d "tests/e2e" ]; then
  echo -e "${RED}Error: Please run this script from the wordpress-dev directory${NC}"
  exit 1
fi

# Create logs directory
mkdir -p logs/optimize
LOG_FILE="logs/optimize/optimize-${ACTION}-${CURRENT_DATE}.log"

# Log function
log() {
  echo "[$(date +"%Y-%m-%d %H:%M:%S")] $1" >> "$LOG_FILE"
  if [ "$VERBOSE" = true ] || [ -z "$2" ]; then
    echo "$1"
  else
    echo "$2"
  fi
}

# Function to analyze test performance
analyze_test_performance() {
  log "Analyzing test performance..."
  
  # Check if we have test results
  if [ ! -d "test-results" ]; then
    log "No test results found. Please run tests first."
    return 1
  fi
  
  # Create analysis directory
  mkdir -p "tests/e2e/analysis"
  ANALYSIS_FILE="tests/e2e/analysis/performance-${CURRENT_DATE}.json"
  
  log "Analyzing test duration..."
  
  # Extract test durations from result files
  echo "{" > "$ANALYSIS_FILE"
  echo "  \"date\": \"${CURRENT_DATE}\"," >> "$ANALYSIS_FILE"
  echo "  \"tests\": [" >> "$ANALYSIS_FILE"
  
  first=true
  find test-results -name "*.json" | while read -r file; do
    # Extract test name and duration
    test_name=$(grep -o '"title":"[^"]*"' "$file" | head -1 | cut -d'"' -f4)
    duration=$(grep -o '"duration":[0-9]*' "$file" | cut -d':' -f2)
    
    if [ -n "$test_name" ] && [ -n "$duration" ]; then
      # Convert duration to seconds
      duration_sec=$(echo "scale=2; $duration/1000" | bc)
      
      # Add to JSON
      if [ "$first" = true ]; then
        first=false
      else
        echo "," >> "$ANALYSIS_FILE"
      fi
      
      echo "    {" >> "$ANALYSIS_FILE"
      echo "      \"name\": \"${test_name}\"," >> "$ANALYSIS_FILE"
      echo "      \"duration\": ${duration_sec}" >> "$ANALYSIS_FILE"
      echo -n "    }" >> "$ANALYSIS_FILE"
      
      # Log slow tests
      if (( $(echo "$duration_sec > 5" | bc -l) )); then
        log "Slow test detected: ${test_name} (${duration_sec}s)" "  - Slow: ${test_name} (${duration_sec}s)"
      fi
    fi
  done
  
  echo "" >> "$ANALYSIS_FILE"
  echo "  ]" >> "$ANALYSIS_FILE"
  echo "}" >> "$ANALYSIS_FILE"
  
  log "Performance analysis saved to ${ANALYSIS_FILE}" "Performance analysis complete."
  
  # Analyze wait operations in test files
  log "Analyzing wait operations in test files..."
  
  WAIT_ANALYSIS="tests/e2e/analysis/waits-${CURRENT_DATE}.txt"
  echo "Wait Operations Analysis - ${CURRENT_DATE}" > "$WAIT_ANALYSIS"
  echo "=================================" >> "$WAIT_ANALYSIS"
  echo "" >> "$WAIT_ANALYSIS"
  
  # Find all timeouts in test files
  fixed_timeouts=$(grep -r "timeout:" --include="*.ts" tests/e2e | wc -l)
  fixed_waits=$(grep -r "waitForTimeout" --include="*.ts" tests/e2e | wc -l)
  
  echo "Fixed Timeouts: ${fixed_timeouts}" >> "$WAIT_ANALYSIS"
  echo "Fixed Waits: ${fixed_waits}" >> "$WAIT_ANALYSIS"
  echo "" >> "$WAIT_ANALYSIS"
  
  # List files with the most timeouts
  echo "Files with most timeouts:" >> "$WAIT_ANALYSIS"
  grep -r "timeout:" --include="*.ts" tests/e2e | cut -d: -f1 | sort | uniq -c | sort -nr | head -5 >> "$WAIT_ANALYSIS"
  echo "" >> "$WAIT_ANALYSIS"
  
  echo "Files with most waitForTimeout calls:" >> "$WAIT_ANALYSIS"
  grep -r "waitForTimeout" --include="*.ts" tests/e2e | cut -d: -f1 | sort | uniq -c | sort -nr | head -5 >> "$WAIT_ANALYSIS"
  
  log "Wait analysis saved to ${WAIT_ANALYSIS}" "Wait analysis complete."
  
  # Analyze selector complexity
  log "Analyzing selector complexity..."
  
  SELECTOR_ANALYSIS="tests/e2e/analysis/selectors-${CURRENT_DATE}.txt"
  echo "Selector Complexity Analysis - ${CURRENT_DATE}" > "$SELECTOR_ANALYSIS"
  echo "===================================" >> "$SELECTOR_ANALYSIS"
  echo "" >> "$SELECTOR_ANALYSIS"
  
  # Find complex selectors
  echo "Complex selectors:" >> "$SELECTOR_ANALYSIS"
  grep -r "selector.*=" --include="*.ts" tests/e2e/pages | grep -v "import" | sort -u >> "$SELECTOR_ANALYSIS"
  echo "" >> "$SELECTOR_ANALYSIS"
  
  # Count selector types
  echo "Selector types:" >> "$SELECTOR_ANALYSIS"
  echo "  ID selectors: $(grep -r "\('#" --include="*.ts" tests/e2e | wc -l)" >> "$SELECTOR_ANALYSIS"
  echo "  Class selectors: $(grep -r "('\\." --include="*.ts" tests/e2e | wc -l)" >> "$SELECTOR_ANALYSIS"
  echo "  Attribute selectors: $(grep -r "('\[" --include="*.ts" tests/e2e | wc -l)" >> "$SELECTOR_ANALYSIS"
  
  log "Selector analysis saved to ${SELECTOR_ANALYSIS}" "Selector analysis complete."
  
  # Summary
  log "Analysis summary:"
  log "  - Test performance analysis: ${ANALYSIS_FILE}"
  log "  - Wait operations analysis: ${WAIT_ANALYSIS}"
  log "  - Selector complexity analysis: ${SELECTOR_ANALYSIS}"
  
  return 0
}

# Function to fix common performance issues
fix_performance_issues() {
  log "Fixing common performance issues..."
  
  # Fix waitForTimeout calls
  log "Replacing fixed waitForTimeout calls with explicit waits..."
  
  FIXED_COUNT=0
  
  # Find all files with waitForTimeout
  files_with_timeouts=$(grep -l "waitForTimeout" --include="*.ts" tests/e2e)
  
  for file in $files_with_timeouts; do
    # Create backup
    cp "$file" "${file}.bak"
    
    # Replace waitForTimeout with explicit waits
    sed -i.tmp 's/await page.waitForTimeout(\([0-9]*\))/await page.waitForLoadState("networkidle")/' "$file"
    
    # Count replacements
    replacements=$(diff "$file" "${file}.bak" | grep "waitForTimeout" | wc -l)
    FIXED_COUNT=$((FIXED_COUNT + replacements))
    
    # Remove temporary files
    rm -f "${file}.tmp"
  done
  
  log "Replaced ${FIXED_COUNT} waitForTimeout calls with explicit waits" "Fixed ${FIXED_COUNT} waitForTimeout calls."
  
  # Optimize selectors in page objects
  log "Optimizing selectors in page objects..."
  
  # Check LoginPage.ts specifically
  if [ -f "tests/e2e/pages/LoginPage.ts" ]; then
    # Check if it's already using the optimized selectors
    if ! grep -q "input\[name=\"log\"\]" "tests/e2e/pages/LoginPage.ts"; then
      log "Updating LoginPage.ts with optimized selectors..."
      
      # Create backup
      cp "tests/e2e/pages/LoginPage.ts" "tests/e2e/pages/LoginPage.ts.bak"
      
      # Update selectors
      sed -i.tmp 's/private readonly usernameInput = '\''#user_login'\'';/private readonly usernameInput = '\''input[name="log"]'\'';/' "tests/e2e/pages/LoginPage.ts"
      sed -i.tmp 's/private readonly passwordInput = '\''#user_pass'\'';/private readonly passwordInput = '\''input[name="pwd"]'\'';/' "tests/e2e/pages/LoginPage.ts"
      sed -i.tmp 's/private readonly loginButton = '\''#wp-submit'\'';/private readonly loginButton = '\''input[type="submit"]'\'';/' "tests/e2e/pages/LoginPage.ts"
      
      # Remove temporary files
      rm -f "tests/e2e/pages/LoginPage.ts.tmp"
      
      log "LoginPage.ts updated with optimized selectors" "LoginPage.ts optimized."
    else
      log "LoginPage.ts already using optimized selectors" "LoginPage.ts already optimized."
    fi
  fi
  
  # Optimize playwright.config.ts
  if [ -f "playwright.config.ts" ]; then
    log "Optimizing Playwright configuration..."
    
    # Create backup
    cp "playwright.config.ts" "playwright.config.ts.bak"
    
    # Check if already optimized
    if ! grep -q "workers: 2" "playwright.config.ts"; then
      # Add worker limit
      sed -i.tmp 's/use: {/use: {\n    workers: 2,/' "playwright.config.ts"
      log "Updated Playwright configuration with worker limit" "Added worker limit to config."
    else
      log "Playwright configuration already has worker limit" "Worker limit already set."
    fi
    
    # Check for retry configuration
    if ! grep -q "retries:" "playwright.config.ts"; then
      # Add retry configuration
      sed -i.tmp 's/projects: \[/retries: process.env.CI ? 2 : 0,\n  projects: \[/' "playwright.config.ts"
      log "Added retry configuration to Playwright config" "Added retry configuration."
    else
      log "Playwright configuration already has retry settings" "Retry settings already configured."
    fi
    
    # Remove temporary files
    rm -f "playwright.config.ts.tmp"
  fi
  
  log "Performance optimizations complete."
  return 0
}

# Function to profile test execution
profile_test_execution() {
  log "Profiling test execution..."
  
  # Create a profile test file
  PROFILE_TEST="tests/e2e/profile-test.spec.ts"
  
  log "Creating profile test..."
  cat > "$PROFILE_TEST" << 'EOF'
import { test } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';
import { TEST_USERS } from './data/test-users';

test('Profile test performance', async ({ page }) => {
  console.time('Total');
  
  // Login page
  const loginPage = new LoginPage(page);
  
  console.time('Navigate to login');
  await loginPage.navigate();
  console.timeEnd('Navigate to login');
  
  console.time('Login');
  await loginPage.login(TEST_USERS.trainer.username, TEST_USERS.trainer.password);
  console.timeEnd('Login');
  
  console.time('Load dashboard');
  await page.waitForLoadState('networkidle');
  console.timeEnd('Load dashboard');
  
  console.time('Screenshot');
  await page.screenshot({ path: 'screenshots/profile-test.png' });
  console.timeEnd('Screenshot');
  
  console.timeEnd('Total');
});
EOF
  
  log "Running profile test..."
  
  # Create profile output directory
  mkdir -p "tests/e2e/profile"
  PROFILE_OUTPUT="tests/e2e/profile/profile-${CURRENT_DATE}.txt"
  
  # Run the profile test with trace
  npx playwright test "$PROFILE_TEST" --trace on > "$PROFILE_OUTPUT" 2>&1
  
  # Extract timing information
  log "Extracting timing information..."
  
  echo "Performance Profile - ${CURRENT_DATE}" > "tests/e2e/profile/summary-${CURRENT_DATE}.txt"
  echo "=================================" >> "tests/e2e/profile/summary-${CURRENT_DATE}.txt"
  echo "" >> "tests/e2e/profile/summary-${CURRENT_DATE}.txt"
  
  # Extract console.time entries
  grep -E "Navigate to login|Login|Load dashboard|Screenshot|Total" "$PROFILE_OUTPUT" | 
    grep -v "console.time" >> "tests/e2e/profile/summary-${CURRENT_DATE}.txt"
  
  # Clean up
  rm "$PROFILE_TEST"
  
  log "Profile results:"
  cat "tests/e2e/profile/summary-${CURRENT_DATE}.txt"
  
  log "Profiling complete. Results saved to tests/e2e/profile/summary-${CURRENT_DATE}.txt"
  return 0
}

# Execute action
case $ACTION in
  "analyze")
    analyze_test_performance
    ;;
  "fix")
    fix_performance_issues
    ;;
  "profile")
    profile_test_execution
    ;;
  *)
    log "Invalid action: ${ACTION}"
    exit 1
    ;;
esac

log "Test optimization ${ACTION} completed successfully."
exit 0