package winkeyer

import "testing"

// The init sequence sent to a K1EL keyer, byte for byte.
//
// This exists because of a bug that no amount of reading caught and that a
// byte-level trace from a real WK2 settled in one line: the dit/dah ratio was
// sent as command 0x11, which is SET KEY COMPENSATION in milliseconds. A
// neutral ratio of 50 therefore asked for 50 ms of extra key-down on every
// element — at 25 wpm a dit is 48 ms — so elements more than doubled and ran
// into each other. The operator saw "one element, then it stalls".
//
// The command NUMBERS are the contract with the hardware. A test on the values
// is the only thing standing between a typo here and a keyer that misbehaves in
// a way nobody can debug from the UI.
func TestApplyConfigCommands(t *testing.T) {
	cmds := configCommands(Config{
		WPM: 25, Weight: 50, Ratio: 50, LeadInMs: 0, TailMs: 0, Sidetone: 0,
	})

	// Every command that must be present, with the value it must carry.
	want := map[byte][]byte{
		0x02: {25},   // speed
		0x03: {50},   // weighting — 50 is neutral, and this one WAS right
		0x17: {50},   // dit/dah ratio — the corrected opcode
		0x11: {0x00}, // key compensation explicitly cleared
	}
	seen := map[byte][]byte{}
	for _, c := range cmds {
		if len(c) < 2 {
			t.Fatalf("command %X has no argument", c)
		}
		seen[c[0]] = c[1:]
	}
	for op, args := range want {
		got, ok := seen[op]
		if !ok {
			t.Errorf("command 0x%02X is not sent at all", op)
			continue
		}
		if len(got) != len(args) || (len(args) > 0 && got[0] != args[0]) {
			t.Errorf("command 0x%02X carries % X, want % X", op, got, args)
		}
	}

	// The ratio must NEVER go out as 0x11 again: that is the whole bug.
	if v, ok := seen[0x11]; ok && len(v) > 0 && v[0] != 0 {
		t.Errorf("0x11 (key compensation) carries %d — it must be 0, not the ratio", v[0])
	}
}

// A keyer left with compensation by an earlier version keeps it in EEPROM, so
// the fix has to CLEAR it rather than merely stop setting it.
func TestKeyCompensationIsCleared(t *testing.T) {
	for _, ratio := range []int{33, 50, 66} {
		cmds := configCommands(Config{WPM: 20, Weight: 50, Ratio: ratio})
		found := false
		for _, c := range cmds {
			if c[0] == 0x11 {
				found = true
				if c[1] != 0 {
					t.Errorf("ratio %d: key compensation sent as %d, want 0", ratio, c[1])
				}
			}
		}
		if !found {
			t.Errorf("ratio %d: key compensation is never cleared", ratio)
		}
	}
}
