package cat

import (
	"errors"
	"testing"
)

// The COM refusal when OmniRig runs elevated and OpsLog does not (or the reverse)
// must be recognised and named. It reached a user as "OmniRig not found" while
// OmniRig sat visibly on screen with its settings window open — so the report was
// a driver hunt that could never succeed.
//
// Windows returns this text localised, so the match cannot rely on English alone;
// the HRESULT (0x800702E4 = ERROR_ELEVATION_REQUIRED) is accepted too.
func TestElevationHint(t *testing.T) {
	recognised := []string{
		"L’opération demandée nécessite une élévation.", // as logged, fr-FR
		"The requested operation requires elevation.",
		"Access denied",
		"Accès refusé",
		"CoCreateInstance failed: 0x800702E4",
	}
	for _, msg := range recognised {
		if elevationHint(errors.New(msg)) == "" {
			t.Errorf("not recognised as a privilege problem: %q", msg)
		}
	}

	// Unrelated failures must NOT be blamed on elevation, or the advice sends the
	// operator to the wrong place just as surely.
	for _, msg := range []string{
		"Classe non enregistrée",
		"REGDB_E_CLASSNOTREG",
		"no CLSID registered for Omnirig.OmnirigX in either registry view",
		"open COM3: Access is den", // truncated word must not match "access denied"
	} {
		if h := elevationHint(errors.New(msg)); h != "" {
			t.Errorf("%q wrongly reported as a privilege problem: %s", msg, h)
		}
	}

	if elevationHint(nil) != "" {
		t.Error("nil error must yield no hint")
	}
}

// The reconnect loop runs every 5 s forever; a persistent failure must be logged
// once, not 1500 times an hour.
func TestLogConnFailureOnlyOncePerCause(t *testing.T) {
	var lines []string
	prev := LogSink
	LogSink = func(format string, args ...any) { lines = append(lines, format) }
	defer func() { LogSink = prev }()

	o := &OmniRig{RigNum: 1}
	for i := 0; i < 20; i++ {
		o.logConnFailure("requires elevation")
	}
	if len(lines) != 1 {
		t.Errorf("logged %d times, want 1", len(lines))
	}
	// A DIFFERENT cause must still be reported.
	o.logConnFailure("class not registered")
	if len(lines) != 2 {
		t.Errorf("a new cause was not logged: %d lines", len(lines))
	}
	// And after reconnecting, the same cause may be reported again.
	o.connLogged = ""
	o.logConnFailure("requires elevation")
	if len(lines) != 3 {
		t.Errorf("after a reconnect the cause should log again: %d lines", len(lines))
	}
}
