package main

// MY_ANTENNA from the Antenna Genius.
//
// A station with a switch has a truth the log does not: which antenna is
// actually connected right now. The working conditions hold what was PLANNED
// for the band — the default antenna ticked for 20 m — and that is right until
// the operator throws the switch, at which point the log quietly keeps claiming
// the other antenna for the rest of the session.
//
// So, as an option: when the Antenna Genius knows which antenna is selected,
// its name wins. The name is the one configured on the device, because that is
// the name the operator gave it and the one they will look for in the log.
//
// WHICH PORT is the whole difficulty. An Antenna Genius has two, A and B, and a
// FlexRadio has two transmit antenna jacks, ANT1 and ANT2. The QSO was made on
// exactly one of them, and stamping the wrong port's antenna would be worse
// than stamping the band default — a wrong answer that looks authoritative. The
// radio's own TX antenna selection is what decides.

import (
	"strings"

	"hamlog/internal/antgenius"
	"hamlog/internal/applog"
)

const (
	keyAntGeniusMyAnt     = "antgenius.my_antenna"    // use the selected antenna as MY_ANTENNA
	keyAntGeniusPortForA1 = "antgenius.port_for_ant1" // which AG port ANT1 is wired to (1=A, 2=B)
)

// antGeniusPortFor maps the radio's transmit antenna jack to an Antenna Genius
// port.
//
// The wiring is the station's, not something that can be read from either
// device: ANT1 usually goes to port A and ANT2 to port B, which is what the
// setting defaults to, but a station wired the other way round would otherwise
// log every QSO with the other antenna's name.
func (a *App) antGeniusPortFor(txAnt string) int {
	ant1Port := 1
	if a.settingOr(keyAntGeniusPortForA1, "1") == "2" {
		ant1Port = 2
	}
	other := 3 - ant1Port
	switch strings.ToUpper(strings.TrimSpace(txAnt)) {
	case "ANT1", "ANT 1", "1", "A":
		return ant1Port
	case "ANT2", "ANT 2", "2", "B":
		return other
	}
	return 0 // XVTR, a rig with one jack, or nothing reported: no port to name
}

// antGeniusAntennaName returns the name of the antenna currently selected on
// the port the radio is transmitting through, or "" when it cannot be told.
//
// Deliberately silent rather than approximate. Every "" here means the log
// keeps the band default it would have had anyway, which is a defensible
// answer; a guessed port is not.
func (a *App) antGeniusAntennaName() string {
	if a.antgenius == nil {
		return ""
	}
	st := a.antgenius.GetStatus()
	if !st.Connected {
		return ""
	}
	// The jack in use comes from the FlexRadio's own state — TXAnt lives on the
	// Flex panel state, not on the backend-agnostic RigState, because only a
	// Flex has named antenna jacks to report.
	txAnt := ""
	if a.cat != nil {
		if fs, ok := a.cat.FlexState(); ok {
			txAnt = fs.TXAnt
		}
	}
	port := a.antGeniusPortFor(txAnt)
	if port == 0 {
		// One switch port in use and no ambiguity about which: a station whose
		// radio has a single jack still deserves the name. Two ports carrying
		// different antennas with nothing to choose between them does not.
		if st.PortA > 0 && st.PortB == 0 {
			port = 1
		} else if st.PortB > 0 && st.PortA == 0 {
			port = 2
		} else {
			return ""
		}
	}
	idx := st.PortA
	if port == 2 {
		idx = st.PortB
	}
	if idx <= 0 {
		return ""
	}
	return antGeniusNameOf(st, idx)
}

// antGeniusNameOf looks an antenna index up in the device's own list.
func antGeniusNameOf(st antgenius.Status, idx int) string {
	for _, ant := range st.Antennas {
		if ant.Index == idx {
			return strings.TrimSpace(ant.Name)
		}
	}
	return ""
}

// applyAntGeniusAntenna overrides MY_ANTENNA with the switch's selection, when
// the option is on.
//
// Called at log time rather than while the entry form is open: an operator who
// changes antenna mid-QSO is telling us what the contact was actually made on,
// and the value that matters is the one at the moment it is logged.
func (a *App) applyAntGeniusAntenna(myAntenna *string) {
	if myAntenna == nil || a.settingOr(keyAntGeniusMyAnt, "") != "1" {
		return
	}
	name := a.antGeniusAntennaName()
	if name == "" {
		return
	}
	if *myAntenna != name {
		applog.Printf("antgenius: MY_ANTENNA %q → %q (the antenna selected on the switch)", *myAntenna, name)
	}
	*myAntenna = name
}
