//go:build windows

package cat

import "testing"

// feed pushes messages at the backend the way the radio would.
func feed(t *TCI, msgs ...string) {
	for _, m := range msgs {
		t.handle(m)
	}
}

// "PTT via CAT does nothing on TCI."
//
// ExpertSDR announces transmit permission with TX_ENABLE — on connect, and
// again whenever the band changes "in case transmitter permission was changed"
// (§4.3 of the protocol document). When it is false the radio simply IGNORES
// trx. OpsLog sent the documented command, the radio discarded it, and nothing
// anywhere said why: the operator pressed a dead key.
func TestPTTIsRefusedOutLoudWhenTheRadioForbidsTransmitting(t *testing.T) {
	tci := NewTCI("localhost", 40001, "FT8", false)
	feed(tci, "tx_enable:0,false")

	err := tci.SetPTT(true)
	if err == nil {
		t.Fatal("keying was accepted while the radio forbids transmitting — the operator gets no reason at all")
	}
	// The message has to name where to look; "PTT failed" sends nobody anywhere.
	for _, want := range []string{"transmit", "ExpertSDR"} {
		if !contains(err.Error(), want) {
			t.Errorf("the refusal reads %q, which does not mention %q", err.Error(), want)
		}
	}

	// Unkeying is never blocked. Whatever the radio thinks about permission, a
	// request to STOP transmitting must always reach it.
	if err := tci.SetPTT(false); err != nil && contains(err.Error(), "refusing") {
		t.Errorf("unkeying was refused: %v", err)
	}
}

// Permission comes back when the operator returns to a band they may use, and
// PTT has to come back with it — not stay blocked until OpsLog is restarted.
func TestPermissionGrantedAgainRestoresPTT(t *testing.T) {
	tci := NewTCI("localhost", 40001, "FT8", false)
	feed(tci, "tx_enable:0,false")
	if err := tci.SetPTT(true); err == nil {
		t.Fatal("keying was accepted while forbidden")
	}
	feed(tci, "tx_enable:0,true")
	// No connection here, so the send fails — but it must fail as a TRANSPORT
	// error, never as a refusal.
	if err := tci.SetPTT(true); err != nil && contains(err.Error(), "refusing") {
		t.Errorf("still refusing after permission was granted: %v", err)
	}
}

// A radio that never mentions TX_ENABLE — an older ExpertSDR, or one of the
// other programs that speak TCI — must not be treated as refusing. Silence is
// not a "no": we key, and let the radio decide.
func TestSilenceAboutPermissionIsNotARefusal(t *testing.T) {
	tci := NewTCI("localhost", 40001, "FT8", false)
	if err := tci.SetPTT(true); err != nil && contains(err.Error(), "refusing") {
		t.Errorf("a radio that never sent TX_ENABLE was treated as forbidding transmit: %v", err)
	}
}

func contains(s, sub string) bool {
	return len(sub) == 0 || (len(s) >= len(sub) && indexOf(s, sub) >= 0)
}

func indexOf(s, sub string) int {
	for i := 0; i+len(sub) <= len(s); i++ {
		if s[i:i+len(sub)] == sub {
			return i
		}
	}
	return -1
}
