#!/usr/bin/env bash
set -euo pipefail

# Run full test suite once (expanded), capture output, parse failed test files, rerun them once, and summarize.
cd "$(dirname "$0")/.."

TARGET_PATH="${1:-}"
OUT="/tmp/flutter_test_$(date +%s).log"

echo "[Full] flutter test -j 1 -r expanded ${TARGET_PATH:+-- $TARGET_PATH} (capturing to $OUT)"
set +e
if [ -n "$TARGET_PATH" ]; then
  flutter test -j 1 -r expanded "$TARGET_PATH" | tee "$OUT"
else
  flutter test -j 1 -r expanded | tee "$OUT"
fi
status_full=${PIPESTATUS[0]}
set -e

# Strip ANSI escape codes for reliable parsing
CLEAN_OUT="${OUT}.clean"
if command -v perl >/dev/null 2>&1; then
  perl -pe 's/\e\[[0-9;]*[A-Za-z]//g' "$OUT" > "$CLEAN_OUT" || cp "$OUT" "$CLEAN_OUT"
else
  # Fallback: naive removal
  sed -E 's/\x1B\[[0-9;]*[A-Za-z]//g' "$OUT" > "$CLEAN_OUT" || cp "$OUT" "$CLEAN_OUT"
fi

failed_files=()
if [ "$status_full" -ne 0 ]; then
  # Extract lines with pattern: "/path/to/file.dart: <desc>"
  while IFS= read -r line; do
    # Attempt to extract the dart file path before the colon
    file=$(echo "$line" | sed -nE 's@^([^:]+\.dart):.*@\1@p')
    if [ -n "$file" ] && [ -f "$file" ]; then
      failed_files+=("$file")
    fi
  done < <(grep -E "^/.+\.dart: " "$CLEAN_OUT" | sort | uniq)

  # Fallback: no parsed files, try a full rerun once to check stability
  if [ ${#failed_files[@]} -eq 0 ]; then
    echo "[Info] Full run failed but no failed files parsed. Trying machine reporter to extract suites..."
    MACHINE_OUT="${OUT}.machine"
    set +e
    if [ -n "$TARGET_PATH" ]; then
      flutter test -j 1 --machine "$TARGET_PATH" > "$MACHINE_OUT" 2>/dev/null
    else
      flutter test -j 1 --machine > "$MACHINE_OUT" 2>/dev/null
    fi
    status_machine=$?
    set -e
    # Extract suitePath values (compatible with macOS bash)
    while IFS= read -r mf; do
      [ -f "$mf" ] && failed_files+=("$mf")
    done < <(grep -oE '"suitePath":"[^"]+\.dart"' "$MACHINE_OUT" | sed -E 's/\\\//g; s/"suitePath":"//; s/"$//' | sort | uniq)
    # If still none, perform a single full rerun as a flake check
    if [ ${#failed_files[@]} -eq 0 ]; then
      echo "[Info] Machine reporter also found no suites. Performing a full rerun once..."
      set +e
      if [ -n "$TARGET_PATH" ]; then
        flutter test -j 1 -r compact "$TARGET_PATH"
      else
        flutter test -j 1 -r compact
      fi
      status_rerun=$?
      set -e
      if [ "$status_rerun" -eq 0 ]; then
        echo "[Rerun] Full rerun passed. Treating as success due to flakiness."
        echo "========================================"
        echo "Full run status: FAILED (first) → PASSED (rerun)"
        echo "Log: $OUT"
        [ -f "$CLEAN_OUT" ] && echo "Clean log: $CLEAN_OUT"
        echo "========================================"
        exit 0
      fi

      # Directory-scoped fallback: run each test file individually; if all pass, treat as success
      if [ -n "$TARGET_PATH" ] && [ -d "$TARGET_PATH" ]; then
        echo "[Info] Falling back to per-file runs under: $TARGET_PATH"
        per_pass=0
        per_count=0
        failed_list=()
        while IFS= read -r tf; do
          per_count=$((per_count+1))
          echo "[Per-File $per_count] flutter test -j 1 -r compact \"$tf\""
          if flutter test -j 1 -r compact "$tf"; then
            per_pass=$((per_pass+1))
          else
            echo "[Per-File] FAILED: $tf"
            failed_list+=("$tf")
          fi
        done < <(find "$TARGET_PATH" -type f -name "*_test.dart" | sort)

        echo "Per-file summary: $per_pass/$per_count passed"
        if [ ${#failed_list[@]} -gt 0 ]; then
          echo "[Per-File] Failed files:"
          printf ' - %s\n' "${failed_list[@]}"
          echo "[Per-File] Rerunning failed files once more to check flakiness..."
          per_rerun_pass=0
          per_rerun_count=${#failed_list[@]}
          for ff in "${failed_list[@]}"; do
            echo "[Per-File Rerun] flutter test -j 1 -r compact \"$ff\""
            if flutter test -j 1 -r compact "$ff"; then
              per_rerun_pass=$((per_rerun_pass+1))
            else
              echo "[Per-File Rerun] STILL FAIL: $ff"
            fi
          done
          echo "[Per-File Rerun] summary: $per_rerun_pass/$per_rerun_count passed"
          # 성공 누적 반영
          per_pass=$((per_pass + per_rerun_pass))
        fi
        if [ "$per_pass" -eq "$per_count" ] && [ "$per_count" -gt 0 ]; then
          echo "[Per-File] All tests passed when run individually. Treating as success due to flakiness."
          exit 0
        fi
      fi
    fi
  fi
fi

repass=0
recount=0
if [ ${#failed_files[@]} -gt 0 ]; then
  echo "[Rerun] Failed files detected:"
  printf ' - %s\n' "${failed_files[@]}"
  for f in "${failed_files[@]}"; do
    recount=$((recount+1))
    echo "[Rerun $recount] flutter test -j 1 -r compact \"$f\""
    if flutter test -j 1 -r compact "$f"; then
      repass=$((repass+1))
    fi
  done
fi

echo "========================================"
echo "Full run status: $( [ "$status_full" -eq 0 ] && echo PASSED || echo FAILED )"
if [ ${#failed_files[@]} -gt 0 ]; then
  echo "Rerun summary: $repass/$recount files passed on rerun"
fi
echo "Log: $OUT"
if [ -f "$CLEAN_OUT" ]; then
  echo "Clean log: $CLEAN_OUT"
fi
echo "========================================"

# Exit 0 if full run passed OR all rerun files passed
if [ "$status_full" -eq 0 ]; then
  exit 0
fi
if [ ${#failed_files[@]} -gt 0 ] && [ "$repass" -eq "$recount" ]; then
  exit 0
fi
exit 1
