//go:build ignore

// Same-language Go stress / benchmark harness.
//
// 고성능 병렬 운용 기준선 Milestone의 lang-baseline Task에서, TypeScript stress.ts와
// 같은 출력 계약(ROW|/SKIP|/SUMMARY|)으로 Go same-language TCP/WS baseline을 남긴다.
// 절대 성능 합격선은 고정하지 않고 local 환경 baseline(throughput, p50/p95/p99 latency,
// peak heap)을 기록하며, 안정성 합격선만 hard fail로 둔다: timeout 0, nonce mismatch 0,
// response type mismatch 0, connection별 FIFO 위반 0, 종료 후 pending leak 0.
//
// 실행: go run ./bench/stress.go [--mode=quick|full] [--transport=tcp,ws] [--profiles=a,b]
package main

import (
	"context"
	"fmt"
	"math/rand"
	"net"
	"os"
	"runtime"
	"sort"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"google.golang.org/protobuf/proto"
	"nhooyr.io/websocket"

	toki "git.toki-labs.com/toki/proto-socket/go"
	"git.toki-labs.com/toki/proto-socket/go/packets"
)

const (
	host     = "127.0.0.1"
	language = "Go"
	wsPath   = "/"
	transTCP = "tcp"
	transWS  = "ws"
)

var allProfiles = []string{"roundtrip", "burst", "sustained", "parallel", "slow-mix", "payload"}

// payload size matrix 축. quick은 작은 샘플(1KB/64KB), full은 Milestone 기준(1KB/64KB/1MB)을 측정한다.
const payloadSeed = "0123456789abcdef"

var (
	payloadSizesQuick = []int{1024, 65536}
	payloadSizesFull  = []int{1024, 65536, 1048576}
)

// stability는 안정성 위반 카운터다. 0이 아니면 해당 row는 FAIL이고 프로세스도 non-zero exit한다.
type stability struct {
	timeouts       atomic.Int64
	nonceMismatch  atomic.Int64
	typeMismatch   atomic.Int64
	fifoViolations atomic.Int64
	pendingLeak    atomic.Int64
}

func (s *stability) violations() int64 {
	return s.timeouts.Load() + s.nonceMismatch.Load() + s.typeMismatch.Load() +
		s.fifoViolations.Load() + s.pendingLeak.Load()
}

type clientHandle struct {
	comm  *toki.Communicator
	send  func(proto.Message) error
	close func() error
}

type serverHandle struct {
	port int
	stop func()
}

var (
	rowsEmitted int
	totalViol   int64
)

func parserMap() toki.ParserMap {
	return toki.ParserMap{
		toki.TypeNameOf(&packets.TestData{}): func(b []byte) (proto.Message, error) {
			m := &packets.TestData{}
			return m, proto.Unmarshal(b, m)
		},
	}
}

func logf(format string, args ...any) {
	fmt.Fprintf(os.Stderr, format+"\n", args...)
}

func memMb() float64 {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)
	return float64(m.HeapAlloc) / (1024 * 1024)
}

func freePort() (int, error) {
	l, err := net.Listen("tcp", host+":0")
	if err != nil {
		return 0, err
	}
	port := l.Addr().(*net.TCPAddr).Port
	_ = l.Close()
	return port, nil
}

func testDataPayloadBytes(message string) int {
	b, err := proto.Marshal(&packets.TestData{Index: 0, Message: message})
	if err != nil {
		return 0
	}
	return len(b)
}

// payloadFiller는 size 바이트 길이의 deterministic filler string을 만든다.
func payloadFiller(size int) string {
	if size <= 0 {
		return ""
	}
	var b strings.Builder
	b.Grow(size + len(payloadSeed))
	for b.Len() < size {
		b.WriteString(payloadSeed)
	}
	return b.String()[:size]
}

// payloadLabel은 payload 크기를 사람이 읽는 축 이름으로 바꾼다(1024 -> 1KB, 1048576 -> 1MB).
func payloadLabel(bytes int) string {
	switch {
	case bytes >= 1048576 && bytes%1048576 == 0:
		return fmt.Sprintf("%dMB", bytes/1048576)
	case bytes >= 1024 && bytes%1024 == 0:
		return fmt.Sprintf("%dKB", bytes/1024)
	default:
		return fmt.Sprintf("%dB", bytes)
	}
}

func percentile(sorted []float64, p float64) float64 {
	if len(sorted) == 0 {
		return 0
	}
	rank := int((p/100.0)*float64(len(sorted))+0.999999) - 1
	if rank < 0 {
		rank = 0
	}
	if rank > len(sorted)-1 {
		rank = len(sorted) - 1
	}
	return sorted[rank]
}

type rowInput struct {
	profile       string
	axis          string
	transport     string
	payloadBytes  int
	clientCount   int
	requests      int
	throughput    float64
	p50, p95, p99 float64
	memMb         float64
	stab          *stability
}

func emitRow(r rowInput) {
	viol := r.stab.violations()
	status := "PASS"
	if viol != 0 {
		status = "FAIL"
	}
	totalViol += viol
	rowsEmitted++
	fields := []string{
		"ROW",
		r.profile,
		r.axis,
		language,
		r.transport,
		fmt.Sprintf("%d", r.payloadBytes),
		fmt.Sprintf("%d", r.clientCount),
		fmt.Sprintf("%d", r.requests),
		fmt.Sprintf("%.1f", r.throughput),
		fmt.Sprintf("%.3f", r.p50),
		fmt.Sprintf("%.3f", r.p95),
		fmt.Sprintf("%.3f", r.p99),
		fmt.Sprintf("%d", r.stab.timeouts.Load()),
		fmt.Sprintf("%d", r.stab.nonceMismatch.Load()),
		fmt.Sprintf("%d", r.stab.typeMismatch.Load()),
		fmt.Sprintf("%d", r.stab.fifoViolations.Load()),
		fmt.Sprintf("%d", r.stab.pendingLeak.Load()),
		"0", // queueBacklog: same-language baseline에는 inbound gateway가 없다.
		"0", // gatewayBacklog
		"off",
		fmt.Sprintf("%.1f", r.memMb),
		status,
	}
	fmt.Println(strings.Join(fields, "|"))
}

func emitSkip(profile, axis, transport, reason string) {
	fmt.Printf("SKIP|%s|%s|%s|%s|%s\n", profile, axis, language, transport, reason)
}

func classifyRequestError(err error, s *stability) {
	msg := err.Error()
	switch {
	case strings.Contains(msg, "timeout") || strings.Contains(msg, "deadline"):
		s.timeouts.Add(1)
	case strings.Contains(msg, "type mismatch"):
		s.typeMismatch.Add(1)
	default:
		s.nonceMismatch.Add(1)
	}
}

// startRequestServer는 request-response echo 서버를 띄운다.
//
// request-response 축에서는 client가 concurrency C로 동시에 send하므로 server의 frame 도착 순서가
// 결정적이지 않다. 따라서 여기서 req.index 단조 증가를 FIFO 위반으로 보면 안 된다. per-connection
// FIFO는 단일 connection에서 순차 send하는 burst 축에서 검증한다. 여기서는 응답 정확성(nonce/type
// matching)과 timeout만 안정성 합격선으로 둔다.
func startRequestServer(ctx context.Context, transport string, s *stability) (*serverHandle, error) {
	port, err := freePort()
	if err != nil {
		return nil, err
	}
	register := func(comm *toki.Communicator) {
		toki.AddRequestListenerTyped[*packets.TestData, *packets.TestData](comm, func(req *packets.TestData) (*packets.TestData, error) {
			return &packets.TestData{Index: req.GetIndex() * 2, Message: "echo:" + req.GetMessage()}, nil
		})
	}
	return startServer(ctx, transport, port, register)
}

func startServer(ctx context.Context, transport string, port int, onConnected func(*toki.Communicator)) (*serverHandle, error) {
	switch transport {
	case transTCP:
		srv := toki.NewTcpServer(host, port, func(conn net.Conn) *toki.TcpClient {
			return toki.NewTcpClient(conn, 0, 0, parserMap())
		})
		srv.OnClientConnected = func(client *toki.TcpClient) { onConnected(&client.Communicator) }
		if err := srv.Start(ctx); err != nil {
			return nil, err
		}
		return &serverHandle{port: port, stop: func() { _ = srv.Stop() }}, nil
	case transWS:
		srv := toki.NewWsServer(host, port, wsPath, func(conn *websocket.Conn) *toki.WsClient {
			return toki.NewWsClient(conn, 0, 0, parserMap())
		})
		srv.OnClientConnected = func(client *toki.WsClient) { onConnected(&client.Communicator) }
		if err := srv.Start(ctx); err != nil {
			return nil, err
		}
		return &serverHandle{port: port, stop: func() { _ = srv.Stop() }}, nil
	default:
		return nil, fmt.Errorf("unknown transport %q", transport)
	}
}

func dial(ctx context.Context, transport string, port int) (*clientHandle, error) {
	switch transport {
	case transTCP:
		c, err := toki.DialTcp(ctx, host, port, 0, 0, parserMap())
		if err != nil {
			return nil, err
		}
		return &clientHandle{comm: &c.Communicator, send: c.Send, close: c.Close}, nil
	case transWS:
		c, err := toki.DialWsWithHeartbeat(ctx, host, port, wsPath, 0, 0, parserMap())
		if err != nil {
			return nil, err
		}
		return &clientHandle{comm: &c.Communicator, send: c.Send, close: c.Close}, nil
	default:
		return nil, fmt.Errorf("unknown transport %q", transport)
	}
}

func dialWithRetry(transport string, port int) (*clientHandle, error) {
	deadline := time.Now().Add(3 * time.Second)
	var lastErr error
	for time.Now().Before(deadline) {
		ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond)
		h, err := dial(ctx, transport, port)
		cancel()
		if err == nil {
			return h, nil
		}
		lastErr = err
		time.Sleep(50 * time.Millisecond)
	}
	return nil, fmt.Errorf("connect %s:%d timed out: %w", transport, port, lastErr)
}

// runRequestLoad는 한 connection에서 concurrency C로 request batch를 보내고 latency를 모은다.
func runRequestLoad(h *clientHandle, total, concurrency int, timeout time.Duration, s *stability) []float64 {
	var mu sync.Mutex
	latencies := make([]float64, 0, total)
	issued := 0
	nextIndex := int32(0)
	for issued < total {
		batchSize := concurrency
		if total-issued < batchSize {
			batchSize = total - issued
		}
		var wg sync.WaitGroup
		for i := 0; i < batchSize; i++ {
			idx := nextIndex
			nextIndex++
			wg.Add(1)
			go func(index int32) {
				defer wg.Done()
				started := time.Now()
				res, err := toki.SendRequestTyped[*packets.TestData, *packets.TestData](
					h.comm,
					&packets.TestData{Index: index, Message: fmt.Sprintf("req-%d", index)},
					timeout,
				)
				if err != nil {
					classifyRequestError(err, s)
					return
				}
				elapsed := float64(time.Since(started).Microseconds()) / 1000.0
				mu.Lock()
				latencies = append(latencies, elapsed)
				mu.Unlock()
				if res.GetIndex() != index*2 || res.GetMessage() != fmt.Sprintf("echo:req-%d", index) {
					s.nonceMismatch.Add(1)
				}
			}(idx)
		}
		issued += batchSize
		wg.Wait()
	}
	return latencies
}

const maxSustainedLatencySamples = 100000

type boundedLatencyCollector struct {
	mu         sync.Mutex
	samples    []float64
	count      int
	maxSamples int
	rng        *rand.Rand
}

func newBoundedLatencyCollector(maxSamples int) *boundedLatencyCollector {
	return &boundedLatencyCollector{
		samples:    make([]float64, 0, 4096),
		maxSamples: maxSamples,
		rng:        rand.New(rand.NewSource(42)),
	}
}

func (c *boundedLatencyCollector) Add(elapsed float64) {
	c.mu.Lock()
	defer c.mu.Unlock()
	c.count++
	if len(c.samples) < c.maxSamples {
		c.samples = append(c.samples, elapsed)
	} else {
		j := c.rng.Intn(c.count)
		if j < c.maxSamples {
			c.samples[j] = elapsed
		}
	}
}

type collectorSnapshot struct {
	samples []float64
	count   int
}

func (c *boundedLatencyCollector) Snapshot() collectorSnapshot {
	c.mu.Lock()
	defer c.mu.Unlock()
	samplesCopy := append([]float64(nil), c.samples...)
	return collectorSnapshot{
		samples: samplesCopy,
		count:   c.count,
	}
}

func summarizeWithCount(profile, axis, transport string, samples []float64, totalCount int, elapsedMs float64, clientCount int, s *stability, observedMem float64) {
	sorted := append([]float64(nil), samples...)
	sort.Float64s(sorted)
	throughput := 0.0
	if elapsedMs > 0 {
		throughput = float64(totalCount) / elapsedMs * 1000.0
	}
	emitRow(rowInput{
		profile:      profile,
		axis:         axis,
		transport:    transport,
		payloadBytes: testDataPayloadBytes("req-0"),
		clientCount:  clientCount,
		requests:     totalCount,
		throughput:   throughput,
		p50:          percentile(sorted, 50),
		p95:          percentile(sorted, 95),
		p99:          percentile(sorted, 99),
		memMb:        observedMem,
		stab:         s,
	})
}

func summarize(profile, axis, transport string, latencies []float64, elapsedMs float64, clientCount int, s *stability, observedMem float64) {
	sorted := append([]float64(nil), latencies...)
	sort.Float64s(sorted)
	throughput := 0.0
	if elapsedMs > 0 {
		throughput = float64(len(latencies)) / elapsedMs * 1000.0
	}
	emitRow(rowInput{
		profile:      profile,
		axis:         axis,
		transport:    transport,
		payloadBytes: testDataPayloadBytes("req-0"),
		clientCount:  clientCount,
		requests:     len(latencies),
		throughput:   throughput,
		p50:          percentile(sorted, 50),
		p95:          percentile(sorted, 95),
		p99:          percentile(sorted, 99),
		memMb:        observedMem,
		stab:         s,
	})
}

func profileRoundtrip(transport string, mode string) {
	concurrencies := []int{1, 16, 64, 256}
	batches := 2
	timeout := 5 * time.Second
	if mode == "full" {
		batches = 20
		timeout = 15 * time.Second
	}
	logf("[roundtrip] transport=%s mode=%s concurrencies=1,16,64,256 batches/level=%d", transport, mode, batches)
	for _, c := range concurrencies {
		s := &stability{}
		total := c * batches
		ctx, cancel := context.WithCancel(context.Background())
		srv, err := startRequestServer(ctx, transport, s)
		if err != nil {
			cancel()
			s.timeouts.Add(1)
			logf("[roundtrip] c=%d server error=%v", c, err)
			summarize("roundtrip", fmt.Sprintf("concurrency=%d", c), transport, nil, 0, 1, s, memMb())
			continue
		}
		h, err := dialWithRetry(transport, srv.port)
		if err != nil {
			s.timeouts.Add(1)
			logf("[roundtrip] c=%d dial error=%v", c, err)
		} else {
			started := time.Now()
			latencies := runRequestLoad(h, total, c, timeout, s)
			elapsed := float64(time.Since(started).Microseconds()) / 1000.0
			summarize("roundtrip", fmt.Sprintf("concurrency=%d", c), transport, latencies, elapsed, 1, s, memMb())
			_ = h.close()
			if h.comm.IsAlive() {
				s.pendingLeak.Add(1)
			}
		}
		srv.stop()
		cancel()
		logf("[roundtrip] transport=%s concurrency=%d done violations=%d", transport, c, s.violations())
	}
}

func profileBurst(transport string, mode string) {
	counts := []int{200}
	if mode == "full" {
		counts = []int{1000, 10000, 100000}
	}
	logf("[burst] transport=%s mode=%s counts=%v", transport, mode, counts)
	for _, count := range counts {
		s := &stability{}
		var received atomic.Int64
		var lastIndex atomic.Int64
		lastIndex.Store(-1)
		done := make(chan struct{})
		var doneOnce sync.Once
		ctx, cancel := context.WithCancel(context.Background())
		srv, err := startServer(ctx, transport, mustPort(), func(comm *toki.Communicator) {
			toki.AddListenerTyped[*packets.TestData](comm, func(msg *packets.TestData) {
				if int64(msg.GetIndex()) <= lastIndex.Load() {
					s.fifoViolations.Add(1)
				}
				lastIndex.Store(int64(msg.GetIndex()))
				if received.Add(1) >= int64(count) {
					doneOnce.Do(func() { close(done) })
				}
			})
		})
		if err != nil {
			cancel()
			s.timeouts.Add(1)
			logf("[burst] count=%d server error=%v", count, err)
			emitThroughput("burst", fmt.Sprintf("count=%d", count), transport, 0, 0, 1, testDataPayloadBytes("b-0"), s, memMb())
			continue
		}
		h, err := dialWithRetry(transport, srv.port)
		if err != nil {
			s.timeouts.Add(1)
			srv.stop()
			cancel()
			emitThroughput("burst", fmt.Sprintf("count=%d", count), transport, 0, 0, 1, testDataPayloadBytes("b-0"), s, memMb())
			continue
		}
		started := time.Now()
		for i := 0; i < count; i++ {
			if err := h.send(&packets.TestData{Index: int32(i), Message: fmt.Sprintf("b-%d", i)}); err != nil {
				s.timeouts.Add(1)
				break
			}
		}
		timeout := 10 * time.Second
		if mode == "full" {
			timeout = 60 * time.Second
		}
		select {
		case <-done:
		case <-time.After(timeout):
			s.timeouts.Add(1)
			logf("[burst] count=%d dispatch timeout received=%d", count, received.Load())
		}
		elapsed := float64(time.Since(started).Microseconds()) / 1000.0
		if received.Load() != int64(count) {
			s.pendingLeak.Add(1)
		}
		emitThroughput("burst", fmt.Sprintf("count=%d", count), transport, count, elapsed, 1, testDataPayloadBytes("b-0"), s, memMb())
		_ = h.close()
		if h.comm.IsAlive() {
			s.pendingLeak.Add(1)
		}
		srv.stop()
		cancel()
		logf("[burst] transport=%s count=%d received=%d violations=%d", transport, count, received.Load(), s.violations())
	}
}

func emitThroughput(profile, axis, transport string, count int, elapsedMs float64, clientCount, payloadBytes int, s *stability, observedMem float64) {
	throughput := 0.0
	if elapsedMs > 0 {
		throughput = float64(count) / elapsedMs * 1000.0
	}
	emitRow(rowInput{
		profile:      profile,
		axis:         axis,
		transport:    transport,
		payloadBytes: payloadBytes,
		clientCount:  clientCount,
		requests:     count,
		throughput:   throughput,
		memMb:        observedMem,
		stab:         s,
	})
}

func profileSustained(transport string, mode string) {
	durationsMs := []int{2000}
	if mode == "full" {
		durationsMs = []int{30000, 300000, 1800000}
	}
	concurrency := 16
	timeout := 15 * time.Second
	logf("[sustained] transport=%s mode=%s durations=%vms concurrency=%d", transport, mode, durationsMs, concurrency)
	for _, durationMs := range durationsMs {
		s := &stability{}
		peak := memMb()
		ctx, cancel := context.WithCancel(context.Background())
		srv, err := startRequestServer(ctx, transport, s)
		if err != nil {
			cancel()
			s.timeouts.Add(1)
			summarize("sustained", fmt.Sprintf("duration=%dms", durationMs), transport, nil, 0, 1, s, peak)
			continue
		}
		h, err := dialWithRetry(transport, srv.port)
		if err != nil {
			s.timeouts.Add(1)
			summarize("sustained", fmt.Sprintf("duration=%dms", durationMs), transport, nil, 0, 1, s, peak)
			srv.stop()
			cancel()
			continue
		}
		// To avoid unbounded memory growth during long sustained runs, we use a bounded
		// latency collector that performs deterministic reservoir sampling.
		// Note: The memory metric for sustained runs is influenced by this sample cap constraint.
		collector := newBoundedLatencyCollector(maxSustainedLatencySamples)
		nextIndex := int32(0)
		deadline := time.Now().Add(time.Duration(durationMs) * time.Millisecond)
		for time.Now().Before(deadline) {
			var wg sync.WaitGroup
			for i := 0; i < concurrency; i++ {
				idx := nextIndex
				nextIndex++
				wg.Add(1)
				go func(index int32) {
					defer wg.Done()
					started := time.Now()
					res, err := toki.SendRequestTyped[*packets.TestData, *packets.TestData](
						h.comm, &packets.TestData{Index: index, Message: fmt.Sprintf("s-%d", index)}, timeout)
					if err != nil {
						classifyRequestError(err, s)
						return
					}
					elapsed := float64(time.Since(started).Microseconds()) / 1000.0
					collector.Add(elapsed)
					if res.GetIndex() != index*2 || res.GetMessage() != fmt.Sprintf("echo:s-%d", index) {
						s.nonceMismatch.Add(1)
					}
				}(idx)
			}
			wg.Wait()
			if cur := memMb(); cur > peak {
				peak = cur
			}
		}
		snapshot := collector.Snapshot()
		summarizeWithCount("sustained", fmt.Sprintf("duration=%dms", durationMs), transport, snapshot.samples, snapshot.count, float64(durationMs), 1, s, peak)
		_ = h.close()
		if h.comm.IsAlive() {
			s.pendingLeak.Add(1)
		}
		srv.stop()
		cancel()
		logf("[sustained] transport=%s duration=%dms done peakMemMb=%.1f violations=%d", transport, durationMs, peak, s.violations())
	}
}

func profileParallel(transport string, mode string) {
	clientCounts := []int{4}
	perClient := 50
	if mode == "full" {
		clientCounts = []int{16, 128, 512, 1024}
		perClient = 500
	}
	concurrency := 8
	timeout := 15 * time.Second
	logf("[parallel] transport=%s mode=%s clients=%v perClient=%d", transport, mode, clientCounts, perClient)
	for _, clientCount := range clientCounts {
		s := &stability{}
		ctx, cancel := context.WithCancel(context.Background())
		srv, err := startRequestServer(ctx, transport, s)
		if err != nil {
			s.timeouts.Add(1)
			summarize("parallel", fmt.Sprintf("clients=%d", clientCount), transport, nil, 0, clientCount, s, memMb())
			cancel()
			continue
		}
		handles := make([]*clientHandle, 0, clientCount)
		for i := 0; i < clientCount; i++ {
			h, err := dialWithRetry(transport, srv.port)
			if err != nil {
				s.timeouts.Add(1)
				continue
			}
			handles = append(handles, h)
		}
		var mu sync.Mutex
		allLatencies := make([]float64, 0, clientCount*perClient)
		started := time.Now()
		var wg sync.WaitGroup
		for _, h := range handles {
			wg.Add(1)
			go func(h *clientHandle) {
				defer wg.Done()
				lat := runRequestLoad(h, perClient, concurrency, timeout, s)
				mu.Lock()
				allLatencies = append(allLatencies, lat...)
				mu.Unlock()
			}(h)
		}
		wg.Wait()
		elapsed := float64(time.Since(started).Microseconds()) / 1000.0
		summarize("parallel", fmt.Sprintf("clients=%d", clientCount), transport, allLatencies, elapsed, clientCount, s, memMb())
		for _, h := range handles {
			_ = h.close()
			if h.comm.IsAlive() {
				s.pendingLeak.Add(1)
			}
		}
		srv.stop()
		cancel()
		logf("[parallel] transport=%s clients=%d done violations=%d", transport, clientCount, s.violations())
	}
}

func profileSlowMix(transport string, mode string) {
	clientCount := 4
	perClient := 20
	slowEvery := 5
	delayMs := 50
	if mode == "full" {
		clientCount = 16
		perClient = 200
		slowEvery = 10
		delayMs = 100
	}
	axis := fmt.Sprintf("clients=%d,slowEvery=%d,delayMs=%d", clientCount, slowEvery, delayMs)
	logf("[slow-mix] transport=%s mode=%s %s perClient=%d", transport, mode, axis, perClient)
	reason := "deferred: optimize Epic — Go public request API does not expose deterministic same-connection in-flight slow/fast response-arrival order; concurrent SendRequestTyped completion order is goroutine-scheduling dependent"
	emitSkip("slow-mix", axis, transport, reason)
	logf("[slow-mix] transport=%s deferred=%s", transport, reason)
}

// profilePayload는 payload size matrix를 측정한다. 동일 connection request-response를 1KB/64KB/1MB
// payload에서 돌리고, message field를 deterministic filler로 채워 실제 serialized payload bytes,
// payload별 p50/p95/p99 latency, throughput, peak heap, stability counters를 결과 row에 남긴다.
func profilePayload(transport string, mode string) {
	sizes := payloadSizesQuick
	concurrency := 4
	requests := 20
	timeout := 10 * time.Second
	if mode == "full" {
		sizes = payloadSizesFull
		concurrency = 8
		requests = 100
		timeout = 30 * time.Second
	}
	labels := make([]string, len(sizes))
	for i, sz := range sizes {
		labels[i] = payloadLabel(sz)
	}
	logf("[payload] transport=%s mode=%s sizes=%s concurrency=%d requests/size=%d",
		transport, mode, strings.Join(labels, ","), concurrency, requests)

	for _, size := range sizes {
		s := &stability{}
		filler := payloadFiller(size)
		expectedEcho := "echo:" + filler
		payloadBytes := testDataPayloadBytes(filler)
		axis := "payload=" + payloadLabel(size)
		peak := memMb()
		ctx, cancel := context.WithCancel(context.Background())
		srv, err := startRequestServer(ctx, transport, s)
		if err != nil {
			cancel()
			s.timeouts.Add(1)
			logf("[payload] size=%s server error=%v", payloadLabel(size), err)
			emitRow(rowInput{profile: "payload", axis: axis, transport: transport, payloadBytes: payloadBytes, clientCount: 1, memMb: peak, stab: s})
			continue
		}
		h, err := dialWithRetry(transport, srv.port)
		if err != nil {
			s.timeouts.Add(1)
			logf("[payload] size=%s dial error=%v", payloadLabel(size), err)
			emitRow(rowInput{profile: "payload", axis: axis, transport: transport, payloadBytes: payloadBytes, clientCount: 1, memMb: peak, stab: s})
			srv.stop()
			cancel()
			continue
		}
		var mu sync.Mutex
		latencies := make([]float64, 0, requests)
		issued := 0
		nextIndex := int32(0)
		started := time.Now()
		for issued < requests {
			batchSize := concurrency
			if requests-issued < batchSize {
				batchSize = requests - issued
			}
			var wg sync.WaitGroup
			for i := 0; i < batchSize; i++ {
				idx := nextIndex
				nextIndex++
				wg.Add(1)
				go func(index int32) {
					defer wg.Done()
					reqStart := time.Now()
					res, err := toki.SendRequestTyped[*packets.TestData, *packets.TestData](
						h.comm, &packets.TestData{Index: index, Message: filler}, timeout)
					if err != nil {
						classifyRequestError(err, s)
						return
					}
					elapsed := float64(time.Since(reqStart).Microseconds()) / 1000.0
					mu.Lock()
					latencies = append(latencies, elapsed)
					mu.Unlock()
					if res.GetIndex() != index*2 || res.GetMessage() != expectedEcho {
						s.nonceMismatch.Add(1)
					}
				}(idx)
			}
			issued += batchSize
			wg.Wait()
			if cur := memMb(); cur > peak {
				peak = cur
			}
		}
		elapsedMs := float64(time.Since(started).Microseconds()) / 1000.0
		sorted := append([]float64(nil), latencies...)
		sort.Float64s(sorted)
		throughput := 0.0
		if elapsedMs > 0 {
			throughput = float64(len(latencies)) / elapsedMs * 1000.0
		}
		emitRow(rowInput{
			profile:      "payload",
			axis:         axis,
			transport:    transport,
			payloadBytes: payloadBytes,
			clientCount:  1,
			requests:     len(latencies),
			throughput:   throughput,
			p50:          percentile(sorted, 50),
			p95:          percentile(sorted, 95),
			p99:          percentile(sorted, 99),
			memMb:        peak,
			stab:         s,
		})
		_ = h.close()
		if h.comm.IsAlive() {
			s.pendingLeak.Add(1)
		}
		srv.stop()
		cancel()
		logf("[payload] transport=%s size=%s bytes=%d peakMemMb=%.1f violations=%d",
			transport, payloadLabel(size), payloadBytes, peak, s.violations())
	}
}

// mustPort는 burst 헬퍼에서 free port 확보 실패를 panic이 아니라 0으로 떨어뜨려 server start가 BLOCKED를 유도하게 한다.
func mustPort() int {
	p, err := freePort()
	if err != nil {
		return 0
	}
	return p
}

func parseListArg(argv []string, prefix string, def []string) []string {
	for _, a := range argv {
		if strings.HasPrefix(a, prefix) {
			raw := strings.Split(a[len(prefix):], ",")
			out := make([]string, 0, len(raw))
			for _, v := range raw {
				v = strings.TrimSpace(v)
				if v != "" {
					out = append(out, v)
				}
			}
			if len(out) > 0 {
				return out
			}
		}
	}
	return def
}

func main() {
	argv := os.Args[1:]
	mode := "quick"
	for _, a := range argv {
		switch {
		case a == "--full" || a == "--mode=full":
			mode = "full"
		case a == "--quick" || a == "--mode=quick":
			mode = "quick"
		}
	}
	transports := parseListArg(argv, "--transport=", []string{transTCP, transWS})
	transports = parseListArg(argv, "--transports=", transports)
	profiles := parseListArg(argv, "--profiles=", allProfiles)
	profiles = parseListArg(argv, "--profile=", profiles)

	logf("INFO stress harness language=%s mode=%s transports=%s profiles=%s typeName=%s",
		language, mode, strings.Join(transports, ","), strings.Join(profiles, ","), toki.TypeNameOf(&packets.TestData{}))

	runners := map[string]func(string, string){
		"roundtrip": profileRoundtrip,
		"burst":     profileBurst,
		"sustained": profileSustained,
		"parallel":  profileParallel,
		"slow-mix":  profileSlowMix,
		"payload":   profilePayload,
	}

	for _, transport := range transports {
		if transport != transTCP && transport != transWS {
			emitSkip("all", "transport", transport, "unsupported transport for Go same-language baseline")
			continue
		}
		for _, p := range profiles {
			runner, ok := runners[p]
			if !ok {
				emitSkip(p, "profile", transport, "profile not part of Go same-language baseline (gateway is TypeScript-specific)")
				continue
			}
			runner(transport, mode)
		}
	}

	status := "PASS"
	if totalViol != 0 {
		status = "FAIL"
	}
	fmt.Printf("SUMMARY|status=%s|language=%s|mode=%s|transports=%s|profiles=%s|rows=%d|stability_violations=%d\n",
		status, language, mode, strings.Join(transports, ","), strings.Join(profiles, ","), rowsEmitted, totalViol)
	if status != "PASS" {
		os.Exit(1)
	}
}
