package cat

// "Serial port busy" is a true statement that helps nobody.
//
// A COM port has exactly one owner, and when a rig's port is refused the owner
// is almost always another program on the same desktop — most often OmniRig,
// which stays resident once any application has activated it and keeps the port
// of the rig configured in it. An operator switching from OmniRig to a native
// backend therefore hits this the moment they save: OpsLog is now asking for a
// port OmniRig never let go of. The message named none of that.
//
// It also happens the other way round, and the wording says so rather than
// accusing: a digital application (WSJT-X, JTDX, MSHV) configured on the rig's
// port directly, rather than through OpsLog's CAT sharing, holds it just as
// firmly.

import "strings"

// busyHint returns a sentence to append to an open error, or "" when the error
// is not about the port being taken.
//
// Deliberately not a wrapped error: this is advice for a human reading a log,
// and it must not change how any caller compares the error.
func busyHint(port string, err error) string {
	if err == nil {
		return ""
	}
	msg := strings.ToLower(err.Error())
	busy := strings.Contains(msg, "busy") ||
		strings.Contains(msg, "access is denied") ||
		strings.Contains(msg, "denied") ||
		strings.Contains(msg, "in use")
	if !busy {
		return ""
	}
	return " — another program holds " + port +
		". OmniRig is the usual one (it stays running and keeps the port of the rig configured in it, so a native backend can never have it);" +
		" a digital application pointed straight at the rig instead of at OpsLog's CAT sharing does the same. Close it, then reconnect."
}
