#!/usr/bin/env bash
set -u

usage() {
  cat <<'USAGE'
Usage: run_matrix.sh [--all|--unit|--cross|--proto] [--anchor LANG --direction server|client|both]

Runs Proto Socket proto schema sync, unit/same-language tests, and/or
cross-language communication tests, then prints Markdown PASS/FAIL tables.
Each run also writes a local result record under agent-test/runs/.
Defaults to --all.

Anchor options:
  --anchor LANG       Focus cross tests around dart, go, kotlin, python, or typescript.
  --direction DIR     server, client, or both. Anchor mode runs the anchor same-language
                      test for the self cell and only the selected x5 cross directions.
USAGE
}

normalize_anchor_language() {
  case "$1" in
    dart|Dart|dart.io|Dart.io) echo "Dart" ;;
    go|Go) echo "Go" ;;
    kotlin|Kotlin) echo "Kotlin" ;;
    python|Python) echo "Python" ;;
    typescript|TypeScript|ts|TS) echo "TypeScript" ;;
    *) return 1 ;;
  esac
}

language_slug() {
  case "$1" in
    Dart) echo "dart" ;;
    Go) echo "go" ;;
    Kotlin) echo "kotlin" ;;
    Python) echo "python" ;;
    TypeScript) echo "typescript" ;;
    *) return 1 ;;
  esac
}

mode="all"
mode_set=0
anchor_arg=""
anchor_language=""
anchor_slug=""
direction="both"

while [ "$#" -gt 0 ]; do
  case "$1" in
    --all) mode="all"; mode_set=1 ;;
    --unit) mode="unit"; mode_set=1 ;;
    --cross) mode="cross"; mode_set=1 ;;
    --proto) mode="proto"; mode_set=1 ;;
    --anchor=*) anchor_arg="${1#--anchor=}" ;;
    --anchor)
      shift
      if [ "$#" -eq 0 ]; then
        printf 'Error: --anchor requires a language\n' >&2
        usage >&2
        exit 2
      fi
      anchor_arg="$1"
      ;;
    --direction=*) direction="${1#--direction=}" ;;
    --direction)
      shift
      if [ "$#" -eq 0 ]; then
        printf 'Error: --direction requires server, client, or both\n' >&2
        usage >&2
        exit 2
      fi
      direction="$1"
      ;;
    -h|--help) usage; exit 0 ;;
    *) usage >&2; exit 2 ;;
  esac
  shift
done

if [ -n "$anchor_arg" ]; then
  if ! anchor_language="$(normalize_anchor_language "$anchor_arg")"; then
    printf 'Error: unknown anchor language "%s"\n' "$anchor_arg" >&2
    usage >&2
    exit 2
  fi
  anchor_slug="$(language_slug "$anchor_language")"
  if [ "$mode" = "all" ] && [ "$mode_set" -eq 0 ]; then
    mode="cross"
  elif [ "$mode" != "cross" ]; then
    printf 'Error: --anchor is only supported with --cross\n' >&2
    usage >&2
    exit 2
  fi
fi

if [ -z "$anchor_language" ] && [ "$direction" != "both" ]; then
  printf 'Error: --direction requires --anchor\n' >&2
  usage >&2
  exit 2
fi

case "$direction" in
  server|client|both) ;;
  *)
    printf 'Error: unknown direction "%s". Use: server, client, both\n' "$direction" >&2
    usage >&2
    exit 2
    ;;
esac

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "$script_dir/../../../../.." && pwd)"
log_dir="$(mktemp -d "${TMPDIR:-/tmp}/proto-socket-matrix.XXXXXX")"
run_started_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
run_record_stamp="$(date -u +%Y%m%d-%H%M%S)"
remote_web_env_file="$repo_root/agent-test/local/remote-web.env"
if [ -f "$remote_web_env_file" ]; then
  set -a
  # shellcheck disable=SC1090
  . "$remote_web_env_file"
  set +a
fi
remote_web_host="${PROTO_SOCKET_DART_WEB_REMOTE:-toki@toki-labs.com}"
remote_web_root_expr="${PROTO_SOCKET_DART_WEB_REMOTE_ROOT:-~/agent-work}"
remote_web_repo_name="${PROTO_SOCKET_DART_WEB_REMOTE_REPO:-proto-socket-dart-web}"
remote_web_repo_url="${PROTO_SOCKET_DART_WEB_REMOTE_URL:-$(git -C "$repo_root" config --get remote.origin.url 2>/dev/null || true)}"
remote_web_ref="${PROTO_SOCKET_DART_WEB_REF:-$(git -C "$repo_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo master)}"
remote_web_execution="local"
remote_web_prepare_summary=""

if [ -n "$anchor_language" ]; then
  record_profile="proto-socket-anchor-${anchor_slug}-${direction}-matrix"
else
  case "$mode" in
    all) record_profile="proto-socket-full-matrix" ;;
    unit) record_profile="proto-socket-unit-matrix" ;;
    cross) record_profile="proto-socket-cross-matrix" ;;
    proto) record_profile="proto-socket-proto-sync" ;;
  esac
fi

languages=("Dart" "Go" "Kotlin" "Python" "TypeScript")

declare -A unit_cmds=(
  ["Dart"]="dart pub get && dart test && dart compile js test/browser_ws_import_compile.dart -o /tmp/proto_socket_browser_ws_import_compile.js"
  ["Go"]="go test ./..."
  ["Kotlin"]="./gradlew test"
  ["Python"]="python3 -m pytest -q"
  ["TypeScript"]="npm run check && npm test"
)
declare -A unit_dirs=(
  ["Dart"]="$repo_root/dart"
  ["Go"]="$repo_root/go"
  ["Kotlin"]="$repo_root/kotlin"
  ["Python"]="$repo_root/python"
  ["TypeScript"]="$repo_root/typescript"
)
declare -A unit_result
declare -A unit_status
declare -A unit_summary

proto_cmd="tools/check_proto_sync.sh"
proto_dir="$repo_root"
proto_result="-"
proto_status=""
proto_summary=""

cross_cases=(
  "Go|Dart|$repo_root/go|go run ./crosstest/go_dart.go"
  "Go|Kotlin|$repo_root/go|go run ./crosstest/go_kotlin.go"
  "Go|Python|$repo_root/go|go run ./crosstest/go_python.go"
  "Go|TypeScript|$repo_root/go|go run ./crosstest/go_typescript.go"
  "Dart|Go|$repo_root/dart|dart run crosstest/dart_go.dart"
  "Dart|Kotlin|$repo_root/dart|dart run crosstest/dart_kotlin.dart"
  "Dart|Python|$repo_root/dart|dart run crosstest/dart_python.dart"
  "Dart|TypeScript|$repo_root/dart|dart run crosstest/dart_typescript.dart"
  "Kotlin|Dart|$repo_root/kotlin|./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinDartKt"
  "Kotlin|Go|$repo_root/kotlin|./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinGoKt"
  "Kotlin|Python|$repo_root/kotlin|./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinPythonKt"
  "Kotlin|TypeScript|$repo_root/kotlin|./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinTypescriptKt"
  "Python|Dart|$repo_root/python|python3 crosstest/python_dart.py"
  "Python|Go|$repo_root/python|python3 crosstest/python_go.py"
  "Python|Kotlin|$repo_root/python|python3 crosstest/python_kotlin.py"
  "Python|TypeScript|$repo_root/python|python3 crosstest/python_typescript.py"
  "TypeScript|Dart|$repo_root/typescript|./node_modules/.bin/tsx crosstest/typescript_dart.ts"
  "TypeScript|Go|$repo_root/typescript|./node_modules/.bin/tsx crosstest/typescript_go.ts"
  "TypeScript|Kotlin|$repo_root/typescript|./node_modules/.bin/tsx crosstest/typescript_kotlin.ts"
  "TypeScript|Python|$repo_root/typescript|./node_modules/.bin/tsx crosstest/typescript_python.ts"
)
declare -A cross_result
declare -A cross_status
declare -A cross_pass_lines
declare -A cross_fail_lines
declare -A cross_cmds

expected_cross_pass_lines=17

web_cases=(
  "Dart.io|$repo_root/dart|dart run crosstest/dart_web.dart"
  "Go|$repo_root/go|go run ./crosstest/go_dart_web.go"
  "Kotlin|$repo_root/kotlin|./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinDartWebKt"
  "Python|$repo_root/python|python3 crosstest/python_dart_web.py"
  "TypeScript|$repo_root/typescript|./node_modules/.bin/tsx crosstest/typescript_dart_web.ts"
)
declare -A web_result
declare -A web_ws_result
declare -A web_wss_result
declare -A web_status
declare -A web_pass_lines
declare -A web_ws_pass_lines
declare -A web_wss_pass_lines
declare -A web_fail_lines
declare -A web_cmds
declare -A web_block_reason

expected_web_pass_lines=4
expected_web_transport_pass_lines=2

count_lines() {
  local pattern="$1"
  local file="$2"
  local count
  if command -v rg >/dev/null 2>&1; then
    count="$(rg -c "$pattern" "$file" 2>/dev/null || true)"
  else
    count="$(grep -Ec "$pattern" "$file" 2>/dev/null || true)"
  fi
  echo "${count:-0}"
}

single_quote() {
  printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"
}

remote_exec() {
  local cmd="$1"
  ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_web_host" "zsh -lc $(single_quote "$cmd")"
}

run_logged() {
  local name="$1"
  local dir="$2"
  local cmd="$3"
  local log_file="$4"

  printf 'RUN %s\n' "$name" >&2
  (
    cd "$dir" &&
      bash -c "$cmd"
  ) >"$log_file" 2>&1
}

chrome_available() {
  if [ -n "${CHROME_EXECUTABLE:-}" ] && [ -x "$CHROME_EXECUTABLE" ]; then
    return 0
  fi
  command -v google-chrome >/dev/null 2>&1
}

remote_chrome_export_command() {
  cat <<'REMOTE_CHROME'
if [ -n "${CHROME_EXECUTABLE:-}" ] && [ -x "$CHROME_EXECUTABLE" ]; then
  :
elif [ -n "${repo_dir:-}" ] && [ -x "$repo_dir/.agent-test/chrome-proto-socket-wss" ]; then
  export CHROME_EXECUTABLE="$repo_dir/.agent-test/chrome-proto-socket-wss"
elif [ -x "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" ]; then
  export CHROME_EXECUTABLE="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
elif command -v google-chrome >/dev/null 2>&1; then
  export CHROME_EXECUTABLE="$(command -v google-chrome)"
elif command -v chromium >/dev/null 2>&1; then
  export CHROME_EXECUTABLE="$(command -v chromium)"
elif command -v chromium-browser >/dev/null 2>&1; then
  export CHROME_EXECUTABLE="$(command -v chromium-browser)"
else
  echo "Chrome executable not found on remote." >&2
  exit 90
fi
REMOTE_CHROME
}

remote_chrome_wrapper_setup_command() {
  cat <<'REMOTE_CHROME_WRAPPER'
if [ -x "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" ] &&
   command -v openssl >/dev/null 2>&1 &&
   [ -f dart/test/certs/server.crt ]; then
  mkdir -p "$repo_dir/.agent-test"
  spki="$(openssl x509 -in dart/test/certs/server.crt -pubkey -noout |
    openssl pkey -pubin -outform DER |
    openssl dgst -sha256 -binary |
    openssl base64)"
  cat > "$repo_dir/.agent-test/chrome-proto-socket-wss" <<WRAPPER
#!/usr/bin/env bash
set -e
exec "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --ignore-certificate-errors-spki-list="$spki" --allow-insecure-localhost "\$@"
WRAPPER
  chmod +x "$repo_dir/.agent-test/chrome-proto-socket-wss"
fi
REMOTE_CHROME_WRAPPER
}

prepare_remote_web_repo() {
  local repo_name_q repo_url_q repo_ref_q chrome_cmd chrome_wrapper_cmd

  if [ -z "$remote_web_repo_url" ]; then
    echo "remote repository URL is not configured" >&2
    return 1
  fi

  repo_name_q="$(single_quote "$remote_web_repo_name")"
  repo_url_q="$(single_quote "$remote_web_repo_url")"
  repo_ref_q="$(single_quote "$remote_web_ref")"
  chrome_cmd="$(remote_chrome_export_command)"
  chrome_wrapper_cmd="$(remote_chrome_wrapper_setup_command)"

  remote_exec "
set -e
repo_parent=$remote_web_root_expr
repo_name=$repo_name_q
repo_url=$repo_url_q
repo_ref=$repo_ref_q
mkdir -p \"\$repo_parent\"
repo_dir=\"\$repo_parent/\$repo_name\"
if [ ! -d \"\$repo_dir/.git\" ]; then
  git clone \"\$repo_url\" \"\$repo_dir\"
fi
cd \"\$repo_dir\"
rm -rf .claude/worktrees
if ! git diff --ignore-submodules=all --quiet || ! git diff --cached --ignore-submodules=all --quiet || [ -n \"\$(git ls-files --others --exclude-standard)\" ]; then
  git stash push -u -m \"proto-socket matrix remote test stash \$(date -u +%Y%m%d-%H%M%S)\" >/dev/null
fi
git fetch origin --prune
git checkout \"\$repo_ref\"
git pull --ff-only origin \"\$repo_ref\"
(cd dart && dart pub get)
if [ -f typescript/package.json ]; then
  (cd typescript && npm install)
fi
if [ -f python/pyproject.toml ]; then
  (cd python && python3 -m pip install -e '.[dev]')
fi
$chrome_wrapper_cmd
$chrome_cmd
printf 'remote Dart.web repo: %s\n' \"\$repo_dir\"
printf 'remote Dart.web git ref: %s\n' \"\$(git rev-parse --short HEAD)\"
"
}

sync_remote_web_worktree() {
  local changed_list sync_count
  changed_list="$log_dir/remote_web_changed_files.zlist"
  {
    git -C "$repo_root" diff --name-only -z
    git -C "$repo_root" diff --cached --name-only -z
    git -C "$repo_root" ls-files --others --exclude-standard -z
  } | sort -zu | while IFS= read -r -d '' path; do
    case "$path" in
      .git|.git/*|.claude|.claude/*) continue ;;
    esac
    printf '%s\0' "$path"
  done >"$changed_list"

  if [ ! -s "$changed_list" ]; then
    return 0
  fi

  sync_count="$(tr '\0' '\n' <"$changed_list" | sed '/^$/d' | wc -l | tr -d ' ')"
  (
    cd "$repo_root" &&
      tar --null -T "$changed_list" -cf -
  ) | remote_exec "
set -e
repo_parent=$remote_web_root_expr
repo_name=$(single_quote "$remote_web_repo_name")
repo_dir=\"\$repo_parent/\$repo_name\"
cd \"\$repo_dir\"
tar -xf -
"
  remote_web_prepare_summary="${remote_web_prepare_summary} local worktree sync: ${sync_count} files "
}

run_remote_web_logged() {
  local server="$1"
  local dir="$2"
  local cmd="$3"
  local log_file="$4"
  local rel_dir chrome_cmd rel_dir_q

  rel_dir="${dir#$repo_root/}"
  rel_dir_q="$(single_quote "$rel_dir")"
  chrome_cmd="$(remote_chrome_export_command)"

  printf 'RUN remote web %s->Dart.web: %s\n' "$server" "$cmd" >&2
  remote_exec "
set -e
repo_parent=$remote_web_root_expr
repo_name=$(single_quote "$remote_web_repo_name")
repo_dir=\"\$repo_parent/\$repo_name\"
$chrome_cmd
cd \"\$repo_dir\"/$rel_dir_q
$cmd
" >"$log_file" 2>&1
}

run_unit_test_for_language() {
  local lang="$1"
  local cmd dir log_file status
  cmd="${unit_cmds[$lang]}"
  dir="${unit_dirs[$lang]}"
  log_file="$log_dir/unit_${lang}.log"
  run_logged "unit $lang: $cmd" "$dir" "$cmd" "$log_file"
  status=$?
  unit_status[$lang]="$status"
  if [ "$status" -eq 0 ]; then
    unit_result[$lang]="PASS"
  else
    unit_result[$lang]="FAIL"
  fi
  unit_summary[$lang]="$(tail -n 1 "$log_file" | tr '\n' ' ')"
}

run_unit_tests() {
  local lang
  for lang in "${languages[@]}"; do
    run_unit_test_for_language "$lang"
  done
}

should_run_cross_case() {
  local server="$1"
  local client="$2"
  [ -z "$anchor_language" ] && return 0
  case "$direction" in
    server) [ "$server" = "$anchor_language" ] ;;
    client) [ "$client" = "$anchor_language" ] ;;
    both) [ "$server" = "$anchor_language" ] || [ "$client" = "$anchor_language" ] ;;
  esac
}

run_proto_sync() {
  local log_file status
  log_file="$log_dir/proto_sync.log"
  run_logged "proto sync: $proto_cmd" "$proto_dir" "$proto_cmd" "$log_file"
  status=$?
  proto_status="$status"
  if [ "$status" -eq 0 ]; then
    proto_result="PASS"
  else
    proto_result="FAIL"
  fi
  proto_summary="$(tail -n 1 "$log_file" | tr '\n' ' ')"
}

run_cross_tests() {
  local item server client dir cmd key log_file status pass_count fail_count
  for item in "${cross_cases[@]}"; do
    IFS='|' read -r server client dir cmd <<<"$item"
    should_run_cross_case "$server" "$client" || continue
    key="$server|$client"
    log_file="$log_dir/cross_${server}_${client}.log"
    cross_cmds[$key]="(cd ${dir#$repo_root/} && $cmd)"
    run_logged "cross $server->$client: $cmd" "$dir" "$cmd" "$log_file"
    status=$?
    pass_count="$(count_lines '^PASS scenario=' "$log_file")"
    fail_count="$(count_lines '^FAIL ' "$log_file")"
    cross_status[$key]="$status"
    cross_pass_lines[$key]="$pass_count"
    cross_fail_lines[$key]="$fail_count"
    if [ "$status" -eq 0 ] && [ "$fail_count" -eq 0 ] && [ "$pass_count" -eq "$expected_cross_pass_lines" ]; then
      cross_result[$key]="PASS"
    else
      cross_result[$key]="FAIL"
    fi
  done
}

set_web_result() {
  local key="$1"
  local status="$2"
  local log_file="$3"
  local pass_count fail_count ws_pass_count wss_pass_count

  pass_count="$(count_lines '^PASS scenario=' "$log_file")"
  ws_pass_count="$(count_lines '^PASS scenario=ws-' "$log_file")"
  wss_pass_count="$(count_lines '^PASS scenario=wss-' "$log_file")"
  fail_count="$(count_lines '^FAIL ' "$log_file")"
  web_status[$key]="$status"
  web_pass_lines[$key]="$pass_count"
  web_ws_pass_lines[$key]="$ws_pass_count"
  web_wss_pass_lines[$key]="$wss_pass_count"
  web_fail_lines[$key]="$fail_count"
  if [ "$status" -eq 0 ] && [ "$fail_count" -eq 0 ] && [ "$pass_count" -eq "$expected_web_pass_lines" ]; then
    web_result[$key]="PASS"
  else
    web_result[$key]="FAIL"
  fi
  if [ "$status" -eq 0 ] && [ "$fail_count" -eq 0 ] && [ "$ws_pass_count" -eq "$expected_web_transport_pass_lines" ]; then
    web_ws_result[$key]="PASS"
  else
    web_ws_result[$key]="FAIL"
  fi
  if [ "$status" -eq 0 ] && [ "$fail_count" -eq 0 ] && [ "$wss_pass_count" -eq "$expected_web_transport_pass_lines" ]; then
    web_wss_result[$key]="PASS"
  else
    web_wss_result[$key]="FAIL"
  fi
}

run_web_tests() {
  local item server dir cmd key log_file status remote_reason
  if ! chrome_available; then
    if ! prepare_remote_web_repo >"$log_dir/remote_web_prepare.log" 2>&1; then
      remote_reason="$(tail -n 20 "$log_dir/remote_web_prepare.log" | tr '\n' ' ')"
      for item in "${web_cases[@]}"; do
        IFS='|' read -r server dir cmd <<<"$item"
        key="$server"
        web_cmds[$key]="ssh $remote_web_host '(cd $remote_web_root_expr/$remote_web_repo_name/${dir#$repo_root/} && $cmd)'"
        web_status[$key]="127"
        web_pass_lines[$key]="0"
        web_ws_pass_lines[$key]="0"
        web_wss_pass_lines[$key]="0"
        web_fail_lines[$key]="0"
        web_result[$key]="BLOCKED"
        web_ws_result[$key]="BLOCKED"
        web_wss_result[$key]="BLOCKED"
        web_block_reason[$key]="Remote Dart.web environment unavailable: $remote_reason"
        printf 'BLOCKED remote web %s->Dart.web: %s\n' "$server" "$remote_reason" >&2
      done
      return
    fi
    remote_web_execution="remote"
    remote_web_prepare_summary="$(grep '^remote Dart.web ' "$log_dir/remote_web_prepare.log" 2>/dev/null | tr '\n' ' ')"
    if ! sync_remote_web_worktree >"$log_dir/remote_web_sync.log" 2>&1; then
      remote_reason="$(tail -n 20 "$log_dir/remote_web_sync.log" | tr '\n' ' ')"
      for item in "${web_cases[@]}"; do
        IFS='|' read -r server dir cmd <<<"$item"
        key="$server"
        web_cmds[$key]="ssh $remote_web_host '(cd $remote_web_root_expr/$remote_web_repo_name/${dir#$repo_root/} && $cmd)'"
        web_status[$key]="127"
        web_pass_lines[$key]="0"
        web_ws_pass_lines[$key]="0"
        web_wss_pass_lines[$key]="0"
        web_fail_lines[$key]="0"
        web_result[$key]="BLOCKED"
        web_ws_result[$key]="BLOCKED"
        web_wss_result[$key]="BLOCKED"
        web_block_reason[$key]="Remote Dart.web worktree sync failed: $remote_reason"
        printf 'BLOCKED remote web %s->Dart.web: %s\n' "$server" "$remote_reason" >&2
      done
      return
    fi

    for item in "${web_cases[@]}"; do
      IFS='|' read -r server dir cmd <<<"$item"
      key="$server"
      log_file="$log_dir/web_${server}.log"
      web_cmds[$key]="ssh $remote_web_host '(cd $remote_web_root_expr/$remote_web_repo_name/${dir#$repo_root/} && $cmd)'"
      run_remote_web_logged "$server" "$dir" "$cmd" "$log_file"
      status=$?
      set_web_result "$key" "$status" "$log_file"
    done
    return
  fi

  for item in "${web_cases[@]}"; do
    IFS='|' read -r server dir cmd <<<"$item"
    key="$server"
    log_file="$log_dir/web_${server}.log"
    web_cmds[$key]="(cd ${dir#$repo_root/} && $cmd)"
    run_logged "web $server->Dart.web: $cmd" "$dir" "$cmd" "$log_file"
    status=$?
    set_web_result "$key" "$status" "$log_file"
  done
}

print_proto_table() {
  printf '\n**Proto 동기화**\n'
  printf '| 검사 | 명령 | 결과 |\n'
  printf '|---|---|---|\n'
  printf '| schema sync | `%s` | %s |\n' "$proto_cmd" "$proto_result"
}

print_unit_table() {
  local lang
  local unit_languages=("${languages[@]}")
  if [ -n "$anchor_language" ]; then
    unit_languages=("$anchor_language")
  fi
  printf '\n**동일언어**\n'
  printf '| 언어 | 명령 | 결과 |\n'
  printf '|---|---|---|\n'
  for lang in "${unit_languages[@]}"; do
    printf '| %s | `%s` | %s |\n' "$lang" "${unit_cmds[$lang]}" "${unit_result[$lang]:--}"
  done
}

language_key() {
  local label="$1"
  if [ "$label" = "Dart.io" ]; then
    echo "Dart"
    return
  fi
  echo "$label"
}

display_language_label() {
  local label="$1"
  if [ "$label" = "Dart" ]; then
    echo "Dart.io"
    return
  fi
  echo "$label"
}

language_matrix_cell() {
  local server_label="$1"
  local client_label="$2"
  local server client key

  if [ "$client_label" = "Dart.web" ]; then
    echo "${web_ws_result[$server_label]:--}"
    return
  fi

  if [ "$client_label" = "Dart.web(WSS)" ]; then
    echo "${web_wss_result[$server_label]:--}"
    return
  fi

  server="$(language_key "$server_label")"
  client="$(language_key "$client_label")"
  key="$server|$client"

  if [ "$server" = "$client" ]; then
    if [ -n "${unit_result[$server]:-}" ]; then
      echo "${unit_result[$server]:--}"
    elif [ "$mode" = "all" ] || [ "$mode" = "unit" ]; then
      echo "${unit_result[$server]:--}"
    else
      echo "-"
    fi
    return
  fi

  echo "${cross_result[$key]:--}"
}

print_language_pass_matrix() {
  local server client
  local server_capable=("Dart.io" "Go" "Kotlin" "Python" "TypeScript")
  local servers=("Dart.io" "Go" "Kotlin" "Python" "TypeScript")
  local clients=("Dart.io" "Dart.web" "Dart.web(WSS)" "Go" "Kotlin" "Python" "TypeScript")
  local anchor_label

  if [ -n "$anchor_language" ]; then
    anchor_label="$(display_language_label "$anchor_language")"
    case "$direction" in
      server)
        servers=("$anchor_label")
        clients=("${server_capable[@]}")
        ;;
      client)
        servers=("${server_capable[@]}")
        clients=("$anchor_label")
        ;;
      both)
        servers=("${server_capable[@]}")
        clients=("${server_capable[@]}")
        ;;
    esac
  fi

  printf '\n**언어 PASS 매트릭스**\n'
  printf '| 서버 \\ 클라이언트'
  for client in "${clients[@]}"; do
    printf ' | %s' "$client"
  done
  printf ' |\n'
  printf '|---'
  for client in "${clients[@]}"; do
    printf '|---'
  done
  printf '|\n'
  for server in "${servers[@]}"; do
    printf '| %s' "$server"
    for client in "${clients[@]}"; do
      printf ' | %s' "$(language_matrix_cell "$server" "$client")"
    done
    printf ' |\n'
  done
}

print_cross_detail_table() {
  local item server client dir cmd key
  printf '\n**크로스테스트 상세**\n'
  printf '| 방향 | 결과 | PASS scenarios | Expected | FAIL lines |\n'
  printf '|---|---:|---:|---:|---:|\n'
  for item in "${cross_cases[@]}"; do
    IFS='|' read -r server client dir cmd <<<"$item"
    should_run_cross_case "$server" "$client" || continue
    key="$server|$client"
    printf '| %s -> %s | %s | %s | %s | %s |\n' \
      "$(display_language_label "$server")" "$(display_language_label "$client")" \
      "${cross_result[$key]:--}" "${cross_pass_lines[$key]:--}" "$expected_cross_pass_lines" "${cross_fail_lines[$key]:--}"
  done
  if [ -z "$anchor_language" ]; then
    for item in "${web_cases[@]}"; do
      IFS='|' read -r server dir cmd <<<"$item"
      key="$server"
      printf '| %s -> Dart.web | %s | %s | %s | %s |\n' \
        "$server" "${web_ws_result[$key]:--}" "${web_ws_pass_lines[$key]:--}" "$expected_web_transport_pass_lines" "${web_fail_lines[$key]:--}"
      printf '| %s -> Dart.web(WSS) | %s | %s | %s | %s |\n' \
        "$server" "${web_wss_result[$key]:--}" "${web_wss_pass_lines[$key]:--}" "$expected_web_transport_pass_lines" "${web_fail_lines[$key]:--}"
    done
  fi
}

print_failures() {
  local failed=0
  local lang item server client dir cmd key log_file

  if [ "${proto_result:-}" = "FAIL" ]; then
    failed=1
    log_file="$log_dir/proto_sync.log"
    printf '\n**실패: Proto 동기화 검사**\n'
    printf '재현 명령: `(cd . && %s)`\n\n' "$proto_cmd"
    tail -n 80 "$log_file"
    printf '\n'
  fi

  for lang in "${languages[@]}"; do
    if [ "${unit_result[$lang]:-}" = "FAIL" ]; then
      failed=1
      log_file="$log_dir/unit_${lang}.log"
      printf '\n**실패: %s 유닛/동일언어 테스트**\n' "$lang"
      printf '재현 명령: `(cd %s && %s)`\n\n' "${unit_dirs[$lang]#$repo_root/}" "${unit_cmds[$lang]}"
      tail -n 80 "$log_file"
      printf '\n'
    fi
  done

  for item in "${cross_cases[@]}"; do
    IFS='|' read -r server client dir cmd <<<"$item"
    should_run_cross_case "$server" "$client" || continue
    key="$server|$client"
    if [ "${cross_result[$key]:-}" = "FAIL" ]; then
      failed=1
      log_file="$log_dir/cross_${server}_${client}.log"
      printf '\n**실패: %s -> %s 크로스테스트**\n' "$server" "$client"
      printf '재현 명령: `%s`\n\n' "${cross_cmds[$key]}"
      tail -n 80 "$log_file"
      printf '\n'
    fi
  done

  if [ -z "$anchor_language" ]; then
    for item in "${web_cases[@]}"; do
      IFS='|' read -r server dir cmd <<<"$item"
      key="$server"
      if [ "${web_result[$key]:-}" = "BLOCKED" ]; then
        failed=1
        printf '\n**차단: %s -> Dart.web 크로스테스트**\n' "$server"
        printf '재현 명령: `%s`\n' "${web_cmds[$key]}"
        printf '차단 사유: %s\n\n' "${web_block_reason[$key]:-unknown}"
      elif [ "${web_result[$key]:-}" = "FAIL" ]; then
        failed=1
        log_file="$log_dir/web_${server}.log"
        printf '\n**실패: %s -> Dart.web 크로스테스트**\n' "$server"
        printf '재현 명령: `%s`\n\n' "${web_cmds[$key]}"
        tail -n 80 "$log_file"
        printf '\n'
      fi
    done
  fi

  return "$failed"
}

has_blocked_results() {
  local item server dir cmd key
  for item in "${web_cases[@]}"; do
    IFS='|' read -r server dir cmd <<<"$item"
    key="$server"
    if [ "${web_result[$key]:-}" = "BLOCKED" ]; then
      return 0
    fi
  done
  return 1
}

has_fail_results() {
  local lang item server client dir cmd key
  if [ "${proto_result:-}" = "FAIL" ]; then
    return 0
  fi
  for lang in "${languages[@]}"; do
    if [ "${unit_result[$lang]:-}" = "FAIL" ]; then
      return 0
    fi
  done
  for item in "${cross_cases[@]}"; do
    IFS='|' read -r server client dir cmd <<<"$item"
    should_run_cross_case "$server" "$client" || continue
    key="$server|$client"
    if [ "${cross_result[$key]:-}" = "FAIL" ]; then
      return 0
    fi
  done
  for item in "${web_cases[@]}"; do
    IFS='|' read -r server dir cmd <<<"$item"
    key="$server"
    if [ "${web_result[$key]:-}" = "FAIL" ]; then
      return 0
    fi
  done
  return 1
}

overall_result_value() {
  if has_fail_results; then
    echo "FAIL"
  elif has_blocked_results; then
    echo "BLOCKED"
  else
    echo "PASS"
  fi
}

print_report_body() {
  if [ "$mode" = "all" ] || [ "$mode" = "proto" ]; then
    print_proto_table
  fi
  if [ "$mode" = "all" ] || [ "$mode" = "unit" ]; then
    print_unit_table
  fi
  if [ "$mode" = "cross" ] && [ -n "$anchor_language" ]; then
    print_unit_table
  fi
  if [ "$mode" = "all" ] || [ "$mode" = "cross" ]; then
    print_language_pass_matrix
    print_cross_detail_table
  fi

  printf '\n로그 디렉터리: `%s`\n' "$log_dir"

  if print_failures; then
    return 0
  fi
  return 1
}

write_result_record() {
  local report_body="$1"
  local exit_code="$2"
  local overall_result record_dir record_file git_ref

  overall_result="$(overall_result_value)"

  record_dir="$repo_root/agent-test/runs"
  mkdir -p "$record_dir"
  record_file="$record_dir/${run_record_stamp}-${record_profile}.md"
  git_ref="$(git -C "$repo_root" rev-parse --short HEAD 2>/dev/null || echo "unknown")"

  {
    printf '%s\n' '---'
    printf 'test_env: local\n'
    printf 'record_type: test-result\n'
    printf 'test_profile: %s\n' "$record_profile"
    printf 'created_at: %s\n' "$run_started_at"
    printf 'overall_result: %s\n' "$overall_result"
    printf '%s\n\n' '---'
    printf '# %s local 결과 기록\n\n' "$record_profile"
    printf '## 실행 정보\n\n'
    printf -- '- 실행 일시: %s\n' "$run_started_at"
    printf -- '- git ref: %s\n' "$git_ref"
    if [ -n "$anchor_language" ]; then
      printf -- '- 실행 명령: `bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --%s --anchor %s --direction %s`\n' "$mode" "$anchor_slug" "$direction"
      printf -- '- anchor: %s\n' "$anchor_slug"
      printf -- '- direction: %s\n' "$direction"
    else
      printf -- '- 실행 명령: `bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --%s`\n' "$mode"
    fi
    printf -- '- exit code: %s\n' "$exit_code"
    printf -- '- 로그 디렉터리: `%s`\n' "$log_dir"
    if [ -z "$anchor_language" ] && { [ "$mode" = "all" ] || [ "$mode" = "cross" ]; }; then
      printf -- '- Dart.web 실행 환경: %s\n' "$remote_web_execution"
      if [ "$remote_web_execution" = "remote" ]; then
        printf -- '- Dart.web remote host: `%s`\n' "$remote_web_host"
        printf -- '- Dart.web remote path: `%s/%s`\n' "$remote_web_root_expr" "$remote_web_repo_name"
        printf -- '- Dart.web remote 준비: %s\n' "$remote_web_prepare_summary"
      fi
    fi
    printf -- '- 전체 결과값: %s\n\n' "$overall_result"
    printf '## git status 요약\n\n'
    printf '```text\n'
    git -C "$repo_root" status --short 2>/dev/null || true
    printf '```\n\n'
    cat "$report_body"
  } >"$record_file"

  printf '%s' "$record_file"
}

main() {
  local report_body exit_code record_file display_record_file

  case "$mode" in
    all)
      run_proto_sync
      run_unit_tests
      run_cross_tests
      run_web_tests
      ;;
    unit)
      run_unit_tests
      ;;
    cross)
      if [ -n "$anchor_language" ]; then
        run_unit_test_for_language "$anchor_language"
        run_cross_tests
      else
        run_cross_tests
        run_web_tests
      fi
      ;;
    proto)
      run_proto_sync
      ;;
  esac

  report_body="$log_dir/report.md"
  if print_report_body >"$report_body"; then
    exit_code=0
  else
    exit_code=1
  fi

  record_file="$(write_result_record "$report_body" "$exit_code")"
  cat "$report_body"
  display_record_file="${record_file#$repo_root/}"
  printf '\n결과 기록 파일: `%s`\n' "$display_record_file"

  exit "$exit_code"
}

main "$@"
