//go:build dev

package bundler

import (
	"bufio"
	"bytes"
	"testing"
)

// The canonical handshake vector from RFC 6455 §1.3.
func TestComputeAccept(t *testing.T) {
	got := computeAccept("dGhlIHNhbXBsZSBub25jZQ==")
	const want = "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
	if got != want {
		t.Fatalf("computeAccept = %q, want %q", got, want)
	}
}

// A masked client frame round-trips through readFrame (payload unmasked, opcode
// preserved) — the path exercised when the browser sends a ping or close.
func TestReadFrameMaskedText(t *testing.T) {
	payload := []byte("hello hmr")
	mask := [4]byte{0x12, 0x34, 0x56, 0x78}

	var buf bytes.Buffer
	buf.WriteByte(0x80 | opText)             // FIN + text
	buf.WriteByte(0x80 | byte(len(payload))) // MASK + len
	buf.Write(mask[:])
	for i, b := range payload {
		buf.WriteByte(b ^ mask[i%4])
	}

	op, got, err := readFrame(bufio.NewReader(&buf))
	if err != nil {
		t.Fatalf("readFrame: %v", err)
	}
	if op != opText {
		t.Errorf("opcode = %#x, want %#x", op, opText)
	}
	if !bytes.Equal(got, payload) {
		t.Errorf("payload = %q, want %q", got, payload)
	}
}

// A server frame is written unmasked and parses back to the same payload.
func TestWriteFrameRoundTrip(t *testing.T) {
	payload := bytes.Repeat([]byte("x"), 300) // exercises the 16-bit length path
	var raw bytes.Buffer
	c := &wsClient{brw: bufio.NewReadWriter(bufio.NewReader(nil), bufio.NewWriter(&raw))}
	if err := c.writeText(payload); err != nil {
		t.Fatalf("writeText: %v", err)
	}
	if raw.Bytes()[0] != (0x80 | opText) {
		t.Fatalf("first byte = %#x, want %#x", raw.Bytes()[0], 0x80|opText)
	}
	if raw.Bytes()[1]&0x80 != 0 {
		t.Fatalf("server frame must not set the mask bit")
	}
	op, got, err := readFrame(bufio.NewReader(&raw))
	if err != nil {
		t.Fatalf("readFrame: %v", err)
	}
	if op != opText || !bytes.Equal(got, payload) {
		t.Errorf("round-trip mismatch: op=%#x len=%d", op, len(got))
	}
}
