package udp

import (
	"bytes"
	"testing"
)

// The Halt Tx datagram, byte for byte. A wrong byte here does not fail loudly —
// WSJT-X drops a malformed packet in silence, and the operator sees a Halt
// button that simply does nothing.
func TestEncodeHaltTx(t *testing.T) {
	tests := []struct {
		name       string
		id         string
		autoTxOnly bool
		want       []byte
	}{
		{
			name: "halt now",
			id:   "WSJT-X",
			want: []byte{
				0xad, 0xbc, 0xcb, 0xda, // magic
				0x00, 0x00, 0x00, 0x02, // schema 2
				0x00, 0x00, 0x00, 0x08, // type 8 — Halt Tx
				0x00, 0x00, 0x00, 0x06, // id length
				'W', 'S', 'J', 'T', '-', 'X',
				0x00, // auto_tx_only = false → stop mid-over
			},
		},
		{
			name:       "finish the over first",
			id:         "MSHV",
			autoTxOnly: true,
			want: []byte{
				0xad, 0xbc, 0xcb, 0xda,
				0x00, 0x00, 0x00, 0x02,
				0x00, 0x00, 0x00, 0x08,
				0x00, 0x00, 0x00, 0x04,
				'M', 'S', 'H', 'V',
				0x01,
			},
		},
		{
			// An empty id is length 0, never the -1 that means a null QString:
			// a null where text is expected makes WSJT-X discard the packet.
			name: "empty id is a zero-length string",
			id:   "",
			want: []byte{
				0xad, 0xbc, 0xcb, 0xda,
				0x00, 0x00, 0x00, 0x02,
				0x00, 0x00, 0x00, 0x08,
				0x00, 0x00, 0x00, 0x00,
				0x00,
			},
		},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			got := EncodeHaltTx(tc.id, tc.autoTxOnly)
			if !bytes.Equal(got, tc.want) {
				t.Errorf("EncodeHaltTx(%q, %v)\n got %#v\nwant %#v", tc.id, tc.autoTxOnly, got, tc.want)
			}
		})
	}
}

// SendHaltTx must refuse an empty id rather than broadcast a halt at whatever
// application happens to answer: with two receivers sharing a multicast group,
// halting the wrong one is worse than doing nothing.
func TestSendHaltTxRejectsEmptyID(t *testing.T) {
	m := &Manager{}
	if err := m.SendHaltTx("   ", false); err == nil {
		t.Fatal("expected an error for a blank program id")
	}
}
