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

usage() {
  cat <<'USAGE'
Usage: run_stress.sh [--quick|--full] [--lang a,b,...] [--transport tcp,ws] [--profile a,b,...]

Runs the Proto Socket same-language stress / benchmark harness for one or more language
implementations and writes a single merged local result record under agent-test/runs/.

각 언어 구현은 동일한 출력 계약(ROW|/SKIP|/SUMMARY|)으로 same-language TCP/WS baseline을 낸다.
이 orchestrator는 선택한 언어를 각각 subprocess로 실행하고 결과 row를 하나의 기록으로 병합한다.

Modes:
  --quick   small, fast baseline for smoke/regression (default)
  --full    Load baseline candidates including 100k burst, 5m/30m sustained,
            and 128/512/1024 client candidates where supported

Languages (comma separated, default: all):
  dart go kotlin python typescript

Transports (comma separated, default: tcp,ws):
  tcp  same-language length-prefixed TCP request/response/burst baseline
  ws   same-language WebSocket binary-frame baseline

Profiles (comma separated, default: per-language all):
  roundtrip  request-response latency at concurrency 1/16/64/256
  burst      single-connection fire-and-forget burst ordering / leak check
             (quick: 200, full: 1k/10k/100k)
  sustained  time-boxed sustained request-response with peak memory
             (quick: 2s, full: 30s/5m/30m candidates)
  parallel   multi-connection FIFO / nonce isolation
             (quick: 4 clients, full: 16/128/512/1024 client candidates)
  slow-mix   mixed fast/slow handler load, same-connection delay and cross-connection isolation
             (quick: 4 clients, full: 16 clients)
  payload    payload size matrix request-response (quick: 1KB/64KB, full: 1KB/64KB/1MB)
             with per-payload latency, throughput, peak memory, stability counters
  cross      cross-language request-response correctness / stability adapter
  gateway    (TypeScript only) worker_threads gateway frame-ingest/transport baseline

언어/transport별로 구현이 준비되지 않았거나 toolchain이 없으면 PASS로 기록하지 않고 BLOCKED 또는
SKIPPED(사유 포함)로 남긴다.

Stability pass criteria (hard fail): timeout / nonce mismatch / response type mismatch /
per-connection FIFO violation / pending-queue leak all 0. 절대 throughput/latency는 환경 의존
baseline으로 저장하며 고정 합격선으로 쓰지 않는다. TypeScript TCP full parallel 1024-client row는
single-process event-loop artifact를 피하기 위해 split-process server topology로 측정하고 row axis에
topology를 기록한다.
USAGE
}

mode="quick"
profiles=""
langs=""
transports=""

ALL_LANGS="dart go kotlin python typescript"

while [ "$#" -gt 0 ]; do
  case "$1" in
    --quick) mode="quick" ;;
    --full) mode="full" ;;
    --mode=*) mode="${1#--mode=}" ;;
    --profile=*) profiles="${1#--profile=}" ;;
    --profiles=*) profiles="${1#--profiles=}" ;;
    --profile|--profiles) shift; profiles="${1:-}" ;;
    --lang=*) langs="${1#--lang=}" ;;
    --langs=*) langs="${1#--langs=}" ;;
    --lang|--langs) shift; langs="${1:-}" ;;
    --transport=*) transports="${1#--transport=}" ;;
    --transports=*) transports="${1#--transports=}" ;;
    --transport|--transports) shift; transports="${1:-}" ;;
    -h|--help) usage; exit 0 ;;
    *) usage >&2; exit 2 ;;
  esac
  shift
done

case "$mode" in
  quick|full) ;;
  *) usage >&2; exit 2 ;;
esac

# 콤마/공백 구분을 공백 토큰으로 정규화한다.
normalize_list() { printf '%s' "$1" | tr ',' ' ' | tr -s ' '; }

selected_langs="$(normalize_list "${langs:-$ALL_LANGS}")"
selected_transports="$(normalize_list "${transports:-tcp ws}")"

# 미지원 언어 토큰은 즉시 거른다.
valid_langs=""
for lang in $selected_langs; do
  case " $ALL_LANGS " in
    *" $lang "*) valid_langs="$valid_langs $lang" ;;
    *) printf 'unknown language: %s (valid: %s)\n' "$lang" "$ALL_LANGS" >&2; exit 2 ;;
  esac
done
selected_langs="$(printf '%s' "$valid_langs" | tr -s ' ' | sed 's/^ //')"

# 미지원 transport 토큰도 언어별 harness에 넘기기 전에 즉시 거른다.
valid_transports=""
for transport in $selected_transports; do
  case "$transport" in
    tcp|ws) valid_transports="$valid_transports $transport" ;;
    *) printf 'unknown transport: %s (valid: tcp ws)\n' "$transport" >&2; usage >&2; exit 2 ;;
  esac
done
selected_transports="$(printf '%s' "$valid_transports" | tr -s ' ' | sed 's/^ //')"
[ -n "$selected_transports" ] || { printf 'no transport selected (valid: tcp ws)\n' >&2; usage >&2; exit 2; }

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "$script_dir/../../../../.." && pwd)"

run_started_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
run_record_stamp="$(date -u +%Y%m%d-%H%M%S)"
record_profile="proto-socket-stress-${mode}"
git_ref="$(git -C "$repo_root" rev-parse --short HEAD 2>/dev/null || echo "unknown")"

record_dir="$repo_root/agent-test/runs"
mkdir -p "$record_dir"
record_file="$record_dir/${run_record_stamp}-${record_profile}.md"

work_dir="$(mktemp -d "${TMPDIR:-/tmp}/proto-socket-stress.XXXXXX")"
cleanup() { rm -rf "$work_dir"; }
trap cleanup EXIT

transports_csv="$(printf '%s' "$selected_transports" | tr ' ' ',')"
profiles_csv="$(printf '%s' "$(normalize_list "$profiles")" | tr ' ' ',')"

profile_selected() {
  local needle="$1"
  local selected
  selected="$(normalize_list "$profiles")"
  [ -z "$selected" ] && return 1
  case " $selected " in
    *" $needle "*) return 0 ;;
    *) return 1 ;;
  esac
}

# 사용자 재현용 실행 명령 문자열.
run_cmd="bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stress.sh --$mode"
run_cmd="$run_cmd --lang $(printf '%s' "$selected_langs" | tr ' ' ',')"
run_cmd="$run_cmd --transport $transports_csv"
[ -n "$profiles_csv" ] && run_cmd="$run_cmd --profile $profiles_csv"

lang_available() {
  case "$1" in
    dart) command -v dart >/dev/null 2>&1 ;;
    go) command -v go >/dev/null 2>&1 ;;
    python) command -v python3 >/dev/null 2>&1 ;;
    typescript) [ -x "$repo_root/typescript/node_modules/.bin/tsx" ] ;;
    kotlin) [ -x "$repo_root/kotlin/gradlew" ] && command -v java >/dev/null 2>&1 ;;
  esac
}

lang_block_reason() {
  case "$1" in
    dart) echo "dart SDK not found on PATH" ;;
    go) echo "go toolchain not found on PATH" ;;
    python) echo "python3 not found on PATH" ;;
    typescript) echo "tsx runner not found (run 'npm install' in typescript/)" ;;
    kotlin) echo "kotlin gradlew or JDK not available" ;;
  esac
}

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

cross_command_for() {
  local server="$1" client="$2"
  case "$server|$client" in
    Go\|Dart) echo "$repo_root/go|go run ./crosstest/go_dart.go" ;;
    Go\|Kotlin) echo "$repo_root/go|go run ./crosstest/go_kotlin.go" ;;
    Go\|Python) echo "$repo_root/go|go run ./crosstest/go_python.go" ;;
    Go\|TypeScript) echo "$repo_root/go|go run ./crosstest/go_typescript.go" ;;
    Dart\|Go) echo "$repo_root/dart|dart run crosstest/dart_go.dart" ;;
    Dart\|Kotlin) echo "$repo_root/dart|dart run crosstest/dart_kotlin.dart" ;;
    Dart\|Python) echo "$repo_root/dart|dart run crosstest/dart_python.dart" ;;
    Dart\|TypeScript) echo "$repo_root/dart|dart run crosstest/dart_typescript.dart" ;;
    Kotlin\|Dart) echo "$repo_root/kotlin|./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinDartKt" ;;
    Kotlin\|Go) echo "$repo_root/kotlin|./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinGoKt" ;;
    Kotlin\|Python) echo "$repo_root/kotlin|./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinPythonKt" ;;
    Kotlin\|TypeScript) echo "$repo_root/kotlin|./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinTypescriptKt" ;;
    Python\|Dart) echo "$repo_root/python|python3 crosstest/python_dart.py" ;;
    Python\|Go) echo "$repo_root/python|python3 crosstest/python_go.py" ;;
    Python\|Kotlin) echo "$repo_root/python|python3 crosstest/python_kotlin.py" ;;
    Python\|TypeScript) echo "$repo_root/python|python3 crosstest/python_typescript.py" ;;
    TypeScript\|Dart) echo "$repo_root/typescript|./node_modules/.bin/tsx crosstest/typescript_dart.ts" ;;
    TypeScript\|Go) echo "$repo_root/typescript|./node_modules/.bin/tsx crosstest/typescript_go.ts" ;;
    TypeScript\|Kotlin) echo "$repo_root/typescript|./node_modules/.bin/tsx crosstest/typescript_kotlin.ts" ;;
    TypeScript\|Python) echo "$repo_root/typescript|./node_modules/.bin/tsx crosstest/typescript_python.ts" ;;
  esac
}

cross_transport_count() {
  local _transport="$1" file="$2"
  grep -c '^PASS scenario=' "$file" 2>/dev/null || true
}

cross_expected_count() {
  case "$1" in
    tcp) echo 5 ;;
    ws) echo 4 ;;
    *) echo 4 ;;
  esac
}

run_cross_profile() {
  local cross_record_profile="proto-socket-stress-${mode}-cross"
  local cross_record_file="$record_dir/${run_record_stamp}-${cross_record_profile}.md"
  local overall="PASS"
  local rows_file="$work_dir/cross.rows"
  local summary_file="$work_dir/cross.summary"
  local failures_file="$work_dir/cross.failures"
  : >"$rows_file"
  : >"$summary_file"
  : >"$failures_file"

  local selected_server_slugs selected_client_slugs
  selected_server_slugs="$selected_langs"
  selected_client_slugs="$selected_langs"

  for server_slug in $selected_server_slugs; do
    local server
    server="$(language_label "$server_slug")"
    for client_slug in $selected_client_slugs; do
      local client
      client="$(language_label "$client_slug")"
      [ "$server" = "$client" ] && continue

      local cmd_spec dir cmd key
      cmd_spec="$(cross_command_for "$server" "$client" || true)"
      key="${server}_${client}"
      if [ -z "$cmd_spec" ]; then
        status="SKIPPED"
        note="unsupported cross pair"
        printf '| %s -> %s | %s | 0 | 16 | 0 | %s |\n' "$server" "$client" "$status" "$note" >>"$summary_file"
        continue
      fi
      IFS='|' read -r dir cmd <<<"$cmd_spec"

      if ! lang_available "$server_slug"; then
        status="BLOCKED"
        note="server runtime unavailable: $(lang_block_reason "$server_slug")"
        overall="BLOCKED"
        printf '| %s -> %s | %s | 0 | 16 | 0 | %s |\n' "$server" "$client" "$status" "$note" >>"$summary_file"
        printf -- '- %s -> %s: `%s`; %s\n' "$server" "$client" "(cd ${dir#$repo_root/} && $cmd)" "$note" >>"$failures_file"
        continue
      fi
      if ! lang_available "$client_slug"; then
        status="BLOCKED"
        note="client runtime unavailable: $(lang_block_reason "$client_slug")"
        overall="BLOCKED"
        printf '| %s -> %s | %s | 0 | 16 | 0 | %s |\n' "$server" "$client" "$status" "$note" >>"$summary_file"
        printf -- '- %s -> %s: `%s`; %s\n' "$server" "$client" "(cd ${dir#$repo_root/} && $cmd)" "$note" >>"$failures_file"
        continue
      fi

      for transport in $selected_transports; do
        local expected_for_command
        expected_for_command="$(cross_expected_count "$transport")"
        for concurrency in 1 16 64 256; do
          local log_file start_ns end_ns elapsed_ms pass_total fail_total status note throughput
          log_file="$work_dir/cross_${key}_${transport}_c${concurrency}.log"
          printf 'RUN cross stress server=%s client=%s transport=%s concurrency=%s command=%s\n' "$server" "$client" "$transport" "$concurrency" "$cmd" >&2
          start_ns="$(date +%s%N)"
          ( cd "$dir" && PROTO_SOCKET_CROSSTEST_CONCURRENCY="$concurrency" PROTO_SOCKET_CROSSTEST_TRANSPORT="$transport" bash -c "$cmd" ) >"$log_file" 2>&1
          exit_code=$?
          end_ns="$(date +%s%N)"
          elapsed_ms="$(( (end_ns - start_ns) / 1000000 ))"
          [ "$elapsed_ms" -le 0 ] && elapsed_ms=1
          tail -n 10 "$log_file" >&2 || true

          pass_total="$(cross_transport_count "$transport" "$log_file")"
          fail_total="$(grep -c '^FAIL' "$log_file" 2>/dev/null || true)"
          if [ "$exit_code" -eq 0 ] && [ "$pass_total" -eq "$expected_for_command" ] && [ "$fail_total" -eq 0 ]; then
            status="PASS"
            note=""
          else
            status="FAIL"
            note="transport=$transport concurrency=$concurrency exit=$exit_code pass=$pass_total expected=$expected_for_command fail=$fail_total"
            overall="FAIL"
            printf -- '- %s -> %s %s c%s: `%s`; %s\n' "$server" "$client" "$transport" "$concurrency" \
              "(cd ${dir#$repo_root/} && PROTO_SOCKET_CROSSTEST_CONCURRENCY=$concurrency PROTO_SOCKET_CROSSTEST_TRANSPORT=$transport $cmd)" "$note" >>"$failures_file"
            printf '```text\n' >>"$failures_file"
            tail -n 20 "$log_file" >>"$failures_file" 2>/dev/null || true
            printf '```\n' >>"$failures_file"
          fi
          printf '| %s -> %s %s c%s | %s | %s | %s | %s | %s |\n' "$server" "$client" "$transport" "$concurrency" "$status" "$pass_total" "$expected_for_command" "$fail_total" "$note" >>"$summary_file"

          throughput="$(awk -v req="$concurrency" -v ms="$elapsed_ms" 'BEGIN { printf "%.2f", (req * 1000) / ms }')"
          if [ "$status" = "PASS" ]; then
            printf 'ROW|cross|request-response-c%s|%s->%s|%s|0|%s|%s|%s|%s|%s|%s|0|0|0|0|0|0|0|off|0|PASS\n' \
              "$concurrency" "$server" "$client" "$transport" "$concurrency" "$concurrency" "$throughput" "$elapsed_ms" "$elapsed_ms" "$elapsed_ms" >>"$rows_file"
          else
            printf 'ROW|cross|request-response-c%s|%s->%s|%s|0|%s|%s|0|0|0|0|?|?|?|?|?|0|0|off|0|FAIL\n' \
              "$concurrency" "$server" "$client" "$transport" "$concurrency" "$concurrency" >>"$rows_file"
          fi
        done
      done
    done
  done

  {
    printf '%s\n' '---'
    printf 'test_env: local\n'
    printf 'record_type: stress-result\n'
    printf 'test_profile: %s\n' "$cross_record_profile"
    printf 'created_at: %s\n' "$run_started_at"
    printf 'overall_result: %s\n' "$overall"
    printf '%s\n\n' '---'
    printf '# %s local 결과 기록\n\n' "$cross_record_profile"
    printf '## 실행 정보\n\n'
    printf -- '- 실행 일시: %s\n' "$run_started_at"
    printf -- '- git ref: %s\n' "$git_ref"
    printf -- '- 실행 명령: `%s`\n' "$run_cmd"
    printf -- '- mode: %s\n' "$mode"
    printf -- '- languages: %s\n' "$(printf '%s' "$selected_langs" | tr ' ' ',')"
    printf -- '- transports: %s\n' "$transports_csv"
    printf -- '- profiles: cross\n'
    printf -- '- 전체 결과값: %s\n\n' "$overall"
    printf '## 안정성 합격선\n\n'
    printf -- '- timeout / nonce mismatch / response type mismatch / per-connection FIFO violation / pending-queue leak 모두 0이어야 PASS.\n'
    printf -- '- 이 cross adapter는 기존 crosstest request-response 병렬 scenario를 공통 stress row schema로 기록한다.\n'
    printf -- '- cross adapter는 transport/concurrency 조합마다 `PROTO_SOCKET_CROSSTEST_TRANSPORT`를 지정해 별도 command를 실행한다.\n'
    printf -- '- crosstest command가 실패하거나 선택 transport의 기대 PASS scenario 수와 정확히 일치하지 않으면 해당 row는 FAIL이다.\n\n'
    printf '## 크로스 언어 요약\n\n'
    printf '| 방향 | 결과 | PASS scenarios | Expected | FAIL lines | 비고 |\n'
    printf '|---|---|---:|---:|---:|---|\n'
    cat "$summary_file"
    printf '\n## 측정 결과\n\n'
    printf '| Profile | Axis | Language | Transport | Payload(bytes) | Clients | Requests | Throughput(rps) | p50(ms) | p95(ms) | p99(ms) | Timeout | NonceMis | TypeMis | FIFOViol | PendLeak | QueueBacklog | GatewayBacklog | Gateway | Mem(MB) | 결과 |\n'
    printf '|---|---|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---|---:|---|\n'
    while IFS= read -r row_line; do
      case "$row_line" in ROW\|*) ;; *) continue ;; esac
      IFS='|' read -r _tag profile axis language transport payload clients requests throughput p50 p95 p99 timeouts noncemis typemis fifoviol pendleak queue_backlog gateway_backlog gateway mem status <<<"$row_line"
      printf '| %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s |\n' \
        "$profile" "$axis" "$language" "$transport" "$payload" "$clients" "$requests" "$throughput" "$p50" "$p95" "$p99" \
        "$timeouts" "$noncemis" "$typemis" "$fifoviol" "$pendleak" "$queue_backlog" "$gateway_backlog" "$gateway" "$mem" "$status"
    done <"$rows_file"
    printf '\n## 실패/차단\n\n'
    if [ -s "$failures_file" ]; then
      cat "$failures_file"
    else
      printf -- '- 없음\n'
    fi
    printf '\n## git status 요약\n\n'
    printf '```text\n'
    git -C "$repo_root" status --short 2>/dev/null || true
    printf '```\n\n'
    printf '## 크로스 진행 로그 tail\n\n'
    for log_file in "$work_dir"/cross_*.log; do
      [ -f "$log_file" ] || continue
      printf '### %s\n\n' "$(basename "$log_file" .log)"
      printf '```text\n'
      tail -n 20 "$log_file" 2>/dev/null || true
      printf '```\n\n'
    done
  } >"$cross_record_file"

  printf '\n=== cross stress 측정 결과 ===\n' >&2
  cat "$summary_file" >&2
  printf '\n전체 결과값: %s\n' "$overall"
  printf '결과 기록 파일: `%s`\n' "${cross_record_file#$repo_root/}"
  case "$overall" in
    PASS) exit 0 ;;
    BLOCKED) exit 3 ;;
    *) exit 1 ;;
  esac
}

# SKIP reason을 optional/required로 분류한다.
#
# optional skip은 그 언어의 same-language baseline 대상이 아닌 축이라 전체 PASS를 깨지 않는다
# (예: gateway는 TypeScript 전용, 미지원 transport). required skip은 기본 선택 범위에서 측정돼야 하는
# 축이 측정되지 못한 경우(예: optimize Epic으로 이연된 stability 병목)라, 포함되면 전체 결과를 PASS로
# 기록하지 않는다. 알 수 없는 reason은 안전하게 required로 본다. 반환: required=0, optional=1.
skip_is_required() {
  case "$1" in
    optional:*) return 1 ;;
    *"not part of"*"same-language baseline"*) return 1 ;;
    *"unsupported transport"*) return 1 ;;
    *) return 0 ;;
  esac
}

# 언어별 stress 진입점을 실행한다. stdout=ROW|/SKIP|/SUMMARY|, stderr=진행 로그.
run_lang() {
  local lang="$1" outfile="$2" errfile="$3"
  local margs="--mode=$mode" targs="--transport=$transports_csv"
  local pargs=""
  [ -n "$profiles_csv" ] && pargs="--profiles=$profiles_csv"

  case "$lang" in
    dart)
      ( cd "$repo_root/dart" && dart run bench/stress.dart "$margs" "$targs" ${pargs:+"$pargs"} ) >"$outfile" 2>"$errfile" ;;
    go)
      ( cd "$repo_root/go" && go run ./bench/stress.go "$margs" "$targs" ${pargs:+"$pargs"} ) >"$outfile" 2>"$errfile" ;;
    python)
      ( cd "$repo_root/python" && python3 bench/stress.py "$margs" "$targs" ${pargs:+"$pargs"} ) >"$outfile" 2>"$errfile" ;;
    typescript)
      ( cd "$repo_root/typescript" && ./node_modules/.bin/tsx bench/stress.ts "$margs" "$targs" ${pargs:+"$pargs"} ) >"$outfile" 2>"$errfile" ;;
    kotlin)
      local kargs="$margs $targs"
      [ -n "$pargs" ] && kargs="$kargs $pargs"
      ( cd "$repo_root/kotlin" && ./gradlew --offline -q run -PmainClass=com.tokilabs.proto_socket.crosstest.StressKt --args="$kargs" ) >"$outfile" 2>"$errfile" ;;
  esac
}

if profile_selected "cross"; then
  run_cross_profile
fi

declare -A lang_result
declare -A lang_rows
declare -A lang_skips
declare -A lang_req_skips
declare -A lang_violations
declare -A lang_reason

any_fail=0
any_blocked=0
any_incomplete=0

for lang in $selected_langs; do
  outfile="$work_dir/${lang}.out"
  errfile="$work_dir/${lang}.err"
  : >"$outfile"
  : >"$errfile"
  lang_req_skips[$lang]=0

  if ! lang_available "$lang"; then
    lang_result[$lang]="BLOCKED"
    lang_reason[$lang]="$(lang_block_reason "$lang")"
    lang_rows[$lang]=0
    lang_skips[$lang]=0
    lang_violations[$lang]="?"
    printf 'BLOCKED %s: %s\n' "$lang" "${lang_reason[$lang]}" >&2
    any_blocked=1
    continue
  fi

  printf 'RUN stress lang=%s mode=%s transports=%s profiles=%s\n' \
    "$lang" "$mode" "$transports_csv" "${profiles_csv:-all}" >&2
  run_lang "$lang" "$outfile" "$errfile"
  exit_code=$?

  # 진행 로그를 흘려 사용자가 실행 흐름을 볼 수 있게 한다.
  cat "$errfile" >&2

  summary_line="$(grep '^SUMMARY|' "$outfile" | tail -n 1 || true)"
  rows_count="$(grep -c '^ROW|' "$outfile" 2>/dev/null || true)"
  skips_count="$(grep -c '^SKIP|' "$outfile" 2>/dev/null || true)"
  rows_count="${rows_count:-0}"
  skips_count="${skips_count:-0}"
  lang_rows[$lang]="$rows_count"
  lang_skips[$lang]="$skips_count"

  # SKIP을 optional/required로 분류한다. required skip이 하나라도 있으면 그 언어의 baseline은
  # 측정 범위 안에서 완결되지 않은 것이라 PASS로 보지 않는다.
  req_skips=0
  first_req_reason=""
  while IFS= read -r sline; do
    case "$sline" in SKIP\|*) ;; *) continue ;; esac
    sreason="${sline##*|}"
    if skip_is_required "$sreason"; then
      req_skips=$((req_skips + 1))
      [ -z "$first_req_reason" ] && first_req_reason="$sreason"
    fi
  done <"$outfile"
  lang_req_skips[$lang]="$req_skips"

  status="FAIL"
  violations="?"
  if [ -n "$summary_line" ]; then
    status_field="$(printf '%s' "$summary_line" | tr '|' '\n' | sed -n 's/^status=//p' | head -n 1)"
    violations_field="$(printf '%s' "$summary_line" | tr '|' '\n' | sed -n 's/^stability_violations=//p' | head -n 1)"
    [ -n "$status_field" ] && status="$status_field"
    [ -n "$violations_field" ] && violations="$violations_field"
  elif [ "$exit_code" -eq 0 ] && [ "$rows_count" -gt 0 ]; then
    status="PASS"
  fi
  # exit code와 SUMMARY status가 어긋나면 안전하게 FAIL로 본다.
  if [ "$exit_code" -ne 0 ] && [ "$status" = "PASS" ]; then
    status="FAIL"
  fi
  if [ -z "$summary_line" ] && [ "$rows_count" -eq 0 ]; then
    status="BLOCKED"
    lang_reason[$lang]="harness produced no result (exit=$exit_code); see stderr tail"
  fi
  # stability는 통과했지만 required 축이 SKIP된 경우 baseline 미완결로 본다.
  if [ "$status" = "PASS" ] && [ "$req_skips" -gt 0 ]; then
    status="INCOMPLETE"
    lang_reason[$lang]="required SKIP=$req_skips (${first_req_reason})"
  fi

  lang_result[$lang]="$status"
  lang_violations[$lang]="$violations"

  case "$status" in
    FAIL) any_fail=1 ;;
    BLOCKED) any_blocked=1 ;;
    INCOMPLETE) any_incomplete=1 ;;
  esac
  printf 'DONE %s: %s (rows=%s skips=%s required_skips=%s violations=%s)\n' \
    "$lang" "$status" "$rows_count" "$skips_count" "$req_skips" "$violations" >&2
done

# 전체 결과: 실제 stability 실패가 가장 우선, 그다음 required 축 미충족(INCOMPLETE),
# 그다음 toolchain 미가용(BLOCKED), 모두 없으면 PASS.
if [ "$any_fail" -eq 1 ]; then
  overall_result="FAIL"
elif [ "$any_incomplete" -eq 1 ]; then
  overall_result="INCOMPLETE"
elif [ "$any_blocked" -eq 1 ]; then
  overall_result="BLOCKED"
else
  overall_result="PASS"
fi

build_rows_table() {
  printf '| Profile | Axis | Language | Transport | Payload(bytes) | Clients | Requests | Throughput(rps) | p50(ms) | p95(ms) | p99(ms) | Timeout | NonceMis | TypeMis | FIFOViol | PendLeak | QueueBacklog | GatewayBacklog | Gateway | Mem(MB) | 결과 |\n'
  printf '|---|---|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---|---:|---|\n'
  local line lang
  for lang in $selected_langs; do
    [ -f "$work_dir/${lang}.out" ] || continue
    while IFS= read -r line; do
      case "$line" in ROW\|*) ;; *) continue ;; esac
      IFS='|' read -r _tag profile axis language transport payload clients requests throughput p50 p95 p99 timeouts noncemis typemis fifoviol pendleak queue_backlog gateway_backlog gateway mem status <<<"$line"
      printf '| %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s |\n' \
        "$profile" "$axis" "$language" "$transport" "$payload" "$clients" "$requests" "$throughput" "$p50" "$p95" "$p99" \
        "$timeouts" "$noncemis" "$typemis" "$fifoviol" "$pendleak" "$queue_backlog" "$gateway_backlog" "$gateway" "$mem" "$status"
    done <"$work_dir/${lang}.out"
  done
}

build_skips_table() {
  local has_skip=0 line lang
  for lang in $selected_langs; do
    [ -f "$work_dir/${lang}.out" ] || continue
    if grep -q '^SKIP|' "$work_dir/${lang}.out"; then has_skip=1; fi
  done
  [ "$has_skip" -eq 0 ] && { printf -- '- 없음\n'; return; }
  printf '분류: `required`=기본 선택 범위에서 측정돼야 하나 미충족(전체 PASS 불가), `optional`=해당 언어 baseline 대상 외 축.\n\n'
  printf '| 분류 | Profile | Axis | Language | Transport | 사유 |\n'
  printf '|---|---|---|---|---|---|\n'
  for lang in $selected_langs; do
    [ -f "$work_dir/${lang}.out" ] || continue
    while IFS= read -r line; do
      case "$line" in SKIP\|*) ;; *) continue ;; esac
      IFS='|' read -r _tag profile axis language transport reason <<<"$line"
      local kind="optional"
      skip_is_required "$reason" && kind="required"
      printf '| %s | %s | %s | %s | %s | %s |\n' "$kind" "$profile" "$axis" "$language" "$transport" "$reason"
    done <"$work_dir/${lang}.out"
  done
}

build_lang_summary_table() {
  printf '| 언어 | 결과 | ROW | SKIP(전체) | SKIP(required) | stability_violations | 비고 |\n'
  printf '|---|---|---:|---:|---:|---:|---|\n'
  local lang
  for lang in $selected_langs; do
    printf '| %s | %s | %s | %s | %s | %s | %s |\n' \
      "$lang" "${lang_result[$lang]:--}" "${lang_rows[$lang]:-0}" "${lang_skips[$lang]:-0}" \
      "${lang_req_skips[$lang]:-0}" "${lang_violations[$lang]:-?}" "${lang_reason[$lang]:-}"
  done
}

{
  printf '%s\n' '---'
  printf 'test_env: local\n'
  printf 'record_type: stress-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"
  printf -- '- 실행 명령: `%s`\n' "$run_cmd"
  printf -- '- mode: %s\n' "$mode"
  printf -- '- languages: %s\n' "$(printf '%s' "$selected_langs" | tr ' ' ',')"
  printf -- '- transports: %s\n' "$transports_csv"
  printf -- '- profiles: %s\n' "${profiles_csv:-all}"
  printf -- '- 전체 결과값: %s\n\n' "$overall_result"
  printf '## 안정성 합격선\n\n'
  printf -- '- timeout / nonce mismatch / response type mismatch / per-connection FIFO violation / pending-queue leak 모두 0이어야 PASS.\n'
  printf -- '- 절대 throughput/latency는 환경 의존 baseline으로 저장하며 고정 합격선으로 쓰지 않는다.\n'
  printf -- '- TypeScript TCP full parallel 1024-client row는 single-process event-loop artifact를 피하기 위해 split-process server topology로 측정하며, row axis에 topology를 기록한다.\n'
  printf -- '- 언어/transport별 미지원 또는 미준비 축은 PASS가 아니라 BLOCKED/SKIPPED와 사유로 기록한다.\n'
  printf -- '- 전체 결과값: `PASS`(측정 범위 내 모든 required 축 stability 0) / `FAIL`(stability 위반) / `INCOMPLETE`(stability 위반은 없으나 기본 선택 범위의 required 축이 SKIP되어 baseline 미완결) / `BLOCKED`(toolchain 미가용).\n'
  printf -- '- `INCOMPLETE`는 PASS가 아니며 lang-baseline 완료 신호로 쓸 수 없다. 명시적으로 범위를 줄여 required 축을 제외하면 그 범위 안에서 PASS가 될 수 있다.\n\n'
  printf '## 언어별 요약\n\n'
  build_lang_summary_table
  printf '\n## 측정 결과\n\n'
  build_rows_table
  printf '\n## SKIPPED/BLOCKED 축\n\n'
  build_skips_table
  printf '\n## git status 요약\n\n'
  printf '```text\n'
  git -C "$repo_root" status --short 2>/dev/null || true
  printf '```\n\n'
  printf '## 언어별 진행 로그(stderr) tail\n\n'
  for lang in $selected_langs; do
    [ -f "$work_dir/${lang}.err" ] || continue
    printf '### %s\n\n' "$lang"
    printf '```text\n'
    tail -n 20 "$work_dir/${lang}.err" 2>/dev/null || true
    printf '```\n\n'
  done
} >"$record_file"

# 사용자 콘솔 요약.
printf '\n=== stress 측정 결과 (언어별 요약) ===\n' >&2
build_lang_summary_table >&2
printf '\n전체 결과값: %s\n' "$overall_result"
printf '결과 기록 파일: `%s`\n' "${record_file#$repo_root/}"

case "$overall_result" in
  PASS) exit 0 ;;
  BLOCKED) exit 3 ;;
  INCOMPLETE) exit 4 ;;
  *) exit 1 ;;
esac
