#!/bin/bash

# e2e-test.sh - End-to-end testing script for MCPControl test panel

# Handle command line arguments
ITERATIONS=${1:-1}  # Default to 1 iteration if not specified
MAX_SEQUENCE_LENGTH=6  # Maximum buttons in the sequence

# Function to clean up when script exits
cleanup() {
  echo "Cleaning up..."
  if [ -n "$CHROME_PID" ]; then
    kill $CHROME_PID 2>/dev/null
  fi
  if [ -n "$SERVER_PID" ]; then
    kill $SERVER_PID 2>/dev/null
  fi
  exit $1
}

# Set up trap for cleanup
trap 'cleanup 1' INT TERM

# Initialize success and failure counts
SUCCESS_COUNT=0
FAILURE_COUNT=0

# ANSI color codes
BOLD="\033[1m"
RESET="\033[0m"
MAGENTA="\033[38;2;187;128;255m"
BLUE="\033[38;2;127;187;255m"
CYAN="\033[38;2;94;210;234m"
GREEN="\033[38;2;158;255;142m"
YELLOW="\033[38;2;255;242;102m"
RED="\033[38;2;255;121;121m"
ORANGE="\033[38;2;255;170;83m"
PURPLE="\033[38;2;210;120;255m"
PINK="\033[38;2;255;127;227m"

echo -e "${BOLD}${MAGENTA}🧪 Running ${BLUE}$ITERATIONS${MAGENTA} test iterations${RESET}"

# Main test loop
for ITERATION in $(seq 1 $ITERATIONS); do
  echo ""
  echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
  echo -e "${BOLD}${CYAN}🔄 Test ${ORANGE}$ITERATION${CYAN} of ${ORANGE}$ITERATIONS${RESET}"
  echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"

  # Generate a random sequence of button clicks (0-9, A-F)
  SEQUENCE_LENGTH=$(( (RANDOM % MAX_SEQUENCE_LENGTH) + 1 ))
  BUTTON_SEQUENCE=""
  for i in $(seq 1 $SEQUENCE_LENGTH); do
    # Generate a random button ID (0-9, A-F for hexadecimal)
    BUTTON_ID=$(( RANDOM % 16 ))
    if [ $BUTTON_ID -lt 10 ]; then
      BUTTON_SEQUENCE="${BUTTON_SEQUENCE}${BUTTON_ID}"
    else
      # Convert to A-F
      CHAR_CODE=$(( BUTTON_ID - 10 + 65 ))  # ASCII 'A' starts at 65
      BUTTON_CHAR=$(printf \\$(printf '%03o' $CHAR_CODE))
      BUTTON_SEQUENCE="${BUTTON_SEQUENCE}${BUTTON_CHAR}"
    fi
  done


  # Create temporary log files for this iteration
  LOG_FILE=$(mktemp)
  TEST_EVENTS_LOG=$(mktemp)
  RESULT_FILE=$(mktemp)
  
  # Start the test server
  echo -e "${CYAN}🚀 Starting test server...${RESET}"
  cd "$(dirname "$0")/.."
  
  # Remove any old port file
  rm -f test/server-port.txt
  
  # Start the server and capture output while displaying it in real-time
  node test/test-server.js 2>&1 | tee "$TEST_EVENTS_LOG" &
  SERVER_PID=$!
  
  # Wait for server to be ready and port file to be created
  echo -e "${YELLOW}⏳ Waiting for server...${RESET}"
  MAX_WAIT=10
  for i in $(seq 1 $MAX_WAIT); do
    if [ -f "test/server-port.txt" ]; then
      break
    fi
    sleep 1
    
    # If we've waited too long, abort
    if [ $i -eq $MAX_WAIT ]; then
      echo -e "${RED}❌ Server start failed after $MAX_WAIT seconds${RESET}"
      cat "$TEST_EVENTS_LOG"
      cleanup 1
    fi
  done
  # Ensure a clear new line before server messages appear
  echo -e "\n"
  
  # Read the server port
  SERVER_PORT=$(cat test/server-port.txt)
  echo -e "${GREEN}✓ Server running on port ${CYAN}$SERVER_PORT${RESET}"
  
  # Reset test data
  curl -s "http://localhost:$SERVER_PORT/api/reset" > /dev/null
  
  # Start Chrome with the test server
  echo -e "${BLUE}🌐 Opening Chrome with test panel...${RESET}"
  if [[ -n "$WSL_DISTRO_NAME" || "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
    # Windows
    "/mnt/c/Program Files/Google/Chrome/Application/chrome.exe" --start-fullscreen "http://localhost:$SERVER_PORT" &
  else
    # Linux
    google-chrome --start-fullscreen "http://localhost:$SERVER_PORT" &
  fi
  CHROME_PID=$!
  
  # Wait for Chrome to initialize
  sleep 3
  
  # Create temporary prompt file for Claude
  PROMPT_FILE=$(mktemp)
  cat > "$PROMPT_FILE" << EOL
I need you to click buttons on the test panel in the following sequence: "$BUTTON_SEQUENCE"

1. The buttons have hexadecimal labels 0-9 and A-F, with text labels like "Button 0", "Button A", etc.
2. Click each button in the sequence exactly once, in the order provided.
3. Be precise - only click the buttons in the specified sequence.
4. After completing the sequence, respond with this EXACT confirmation message:
   "MCPTEST_DONE: Clicked button sequence $BUTTON_SEQUENCE"

Each button has a counter underneath showing how many times it's been clicked.
This test verifies MCPControl's ability to precisely automate UI interactions.
EOL

  CONFIG_FILE=$(mktemp)
  cat > "$CONFIG_FILE" << EOL
{
  "mcpServers": {
    "mcpcontrol": {
      "type": "stdio",
      "command": "./mcpcontrol-wrapper.sh",
      "args": [],
      "env": {}
    }
  }
}
EOL

  echo -e "${PURPLE}🤖 Testing with Claude & MCPControl...${RESET}"
  echo -e "${BOLD}${PINK}🎲 Test sequence: ${YELLOW}$BUTTON_SEQUENCE ${CYAN}(${ORANGE}$SEQUENCE_LENGTH${CYAN} buttons)${RESET}"
  cd "$(dirname "$0")/.."
  
  # Launch Claude with verbose output
  echo -e "${PURPLE}Claude's Response: ${RESET}"
  claude --print --mcp-config "$CONFIG_FILE" \
    --allowedTools \
      "mcp__mcpcontrol__click_at" \
      "mcp__mcpcontrol__click_mouse" \
      "mcp__mcpcontrol__double_click" \
      "mcp__mcpcontrol__focus_window" \
      "mcp__mcpcontrol__get_active_window" \
      "mcp__mcpcontrol__get_cursor_position" \
      "mcp__mcpcontrol__get_screen_size" \
      "mcp__mcpcontrol__get_screenshot" \
      "mcp__mcpcontrol__hold_key" \
      "mcp__mcpcontrol__move_mouse" \
      "mcp__mcpcontrol__press_key" \
      "mcp__mcpcontrol__press_key_combination" \
      "mcp__mcpcontrol__scroll_mouse" \
      "mcp__mcpcontrol__type_text" \
    < "$PROMPT_FILE" 2>&1 | tee -a "$LOG_FILE"

  echo -e "\n"
  
  # Kill Chrome
  if [ -n "$CHROME_PID" ]; then
    kill $CHROME_PID 2>/dev/null
  fi
  
  # Get the test results from the server
  echo -e "${BLUE}🔍 Collecting results...${RESET}"
  RESULTS_FILE="test/test-results.json"
  
  # Fetch the latest test results
  curl -s "http://localhost:$SERVER_PORT/api/test-data" > "$RESULTS_FILE"
  
  # Extract the final sequence
  if [ -f "$RESULTS_FILE" ]; then
    # Check if we have a finalSequence
    if grep -q "finalSequence" "$RESULTS_FILE"; then
      # Use jq if available, otherwise use grep/sed
      if command -v jq &> /dev/null; then
        ACTUAL_SEQUENCE=$(jq -r '.finalSequence' "$RESULTS_FILE")
      else
        ACTUAL_SEQUENCE=$(grep -o '"finalSequence":"[^"]*"' "$RESULTS_FILE" | cut -d'"' -f4)
      fi
    else
      echo -e "${RED}⚠️ No sequence found in results${RESET}"
    fi
  else
    echo -e "${RED}⚠️ Failed to retrieve test results${RESET}"
  fi
  
  # If we still don't have a sequence, we have a problem
  if [ -z "$ACTUAL_SEQUENCE" ]; then
    ACTUAL_SEQUENCE=""
  fi
  
  echo -e "${BOLD}${MAGENTA}▶ Results${RESET}"
  echo -e "  ${CYAN}Expected: ${YELLOW}$BUTTON_SEQUENCE${RESET}"
  echo -e "  ${CYAN}Actual:   ${YELLOW}$ACTUAL_SEQUENCE${RESET}"
  
  # Verify test results
  TEST_RESULT="FAILED"
  if [ "$ACTUAL_SEQUENCE" = "$BUTTON_SEQUENCE" ]; then
    echo -e "${BOLD}${GREEN}✅ TEST PASSED${RESET}"
    TEST_RESULT="PASSED"
    ((SUCCESS_COUNT++))
    
    # Save success evidence to a result log
    echo "RESULT: PASS" > "$RESULT_FILE"
    echo "Expected: $BUTTON_SEQUENCE" >> "$RESULT_FILE" 
    echo "Actual: $ACTUAL_SEQUENCE" >> "$RESULT_FILE"
  else
    echo -e "${BOLD}${RED}❌ TEST FAILED${RESET}"
    TEST_RESULT="FAILED"
    ((FAILURE_COUNT++))
    
    # Save failure information to result log
    echo "RESULT: FAIL" > "$RESULT_FILE"
    echo "Expected: $BUTTON_SEQUENCE" >> "$RESULT_FILE"
    echo "Actual: $ACTUAL_SEQUENCE" >> "$RESULT_FILE"
  fi

done  # End of iteration loop

# Print final test summary
echo ""
echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
echo -e "${BOLD}${CYAN}🏁 Test Summary${RESET}"
echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
echo -e "${BOLD}${BLUE}Total iterations:${RESET} ${ORANGE}$ITERATIONS${RESET}"
echo -e "${BOLD}${GREEN}Successful tests:${RESET} ${ORANGE}$SUCCESS_COUNT${RESET}"
echo -e "${BOLD}${RED}Failed tests:${RESET} ${ORANGE}$FAILURE_COUNT${RESET}"
SUCCESS_RATE=$(( (SUCCESS_COUNT * 100) / ITERATIONS ))
echo -e "${BOLD}${CYAN}Success rate:${RESET} ${YELLOW}$SUCCESS_RATE%${RESET}"

# Exit with appropriate code
if [ "$FAILURE_COUNT" -eq 0 ]; then
  echo -e "${BOLD}${GREEN}✅ ALL TESTS PASSED${RESET}"
  cleanup 0
else
  echo -e "${BOLD}${RED}❌ SOME TESTS FAILED${RESET}"
  cleanup 1
fi
