package main

import "testing"

// The order of these tests IS the meaning of the answer, and it was wrong: a
// station new on both the band and the mode was reported as a plain "new band",
// which reads as "you have worked this entity in this mode, just not here" —
// the opposite of the truth. It is also not a slot: a slot is the pair still
// missing when each half is already in the log.
func TestSpotEntityStatus(t *testing.T) {
	for _, c := range []struct {
		name                             string
		worked, haveBand, haveMode, slot bool
		mode                             string
		want                             string
	}{
		{"entity never worked", false, false, false, false, "SSB", "new"},
		{"entity never worked, no mode known", false, false, false, false, "", "new"},

		// The case this exists for.
		{"new band AND new mode", true, false, false, false, "SSB", "new-band-mode"},

		// New band, but the mode is already in the log on another band.
		{"new band only", true, false, true, false, "SSB", "new-band"},
		// New mode, on a band already worked.
		{"new mode only", true, true, false, false, "SSB", "new-mode"},
		// Each half worked, never together: THAT is a slot.
		{"new slot", true, true, true, false, "SSB", "new-slot"},
		{"fully worked", true, true, true, true, "SSB", "worked"},

		// No mode: only the band can be judged, and a guess must never claim new.
		{"no mode, new band", true, false, false, false, "", "new-band"},
		{"no mode, band worked", true, true, false, false, "", "worked"},
	} {
		if got := spotEntityStatus(c.worked, c.haveBand, c.haveMode, c.slot, c.mode); got != c.want {
			t.Errorf("%s: got %q, want %q", c.name, got, c.want)
		}
	}
}

// Every status is reachable, and no two inputs collide on a status that should
// be exclusive — the guard against someone "simplifying" the chain later.
func TestSpotEntityStatusIsExhaustive(t *testing.T) {
	seen := map[string]bool{}
	for _, worked := range []bool{true, false} {
		for _, band := range []bool{true, false} {
			for _, mode := range []bool{true, false} {
				for _, slot := range []bool{true, false} {
					seen[spotEntityStatus(worked, band, mode, slot, "CW")] = true
				}
			}
		}
	}
	for _, want := range []string{"new", "new-band-mode", "new-band", "new-mode", "new-slot", "worked"} {
		if !seen[want] {
			t.Errorf("no combination produces %q — the status is dead", want)
		}
	}
}
