package plugin

import "testing"

func TestSunkenTempleGraph_Registered(t *testing.T) {
	g, ok := zoneGraphRegistry[ZoneSunkenTemple]
	if !ok {
		t.Fatal("zoneSunkenTempleGraph not registered")
	}
	if g.Entry != "sunken_temple.entry" {
		t.Errorf("entry node = %q", g.Entry)
	}
	if g.Boss != "sunken_temple.boss" {
		t.Errorf("boss node = %q", g.Boss)
	}
	// Long-expedition D1-b widened this zone from 10 → 26 nodes so the
	// longest entry→boss walk lands in the T2 [16,20] traversal band.
	// (Sunken Temple is wide by design — no mid-merge means each leaf
	// owns its own chain to the boss.)
	if len(g.Nodes) != 26 {
		t.Errorf("nodes = %d, want 26", len(g.Nodes))
	}
}

// TestSunkenTempleGraph_FourDistinctPaths verifies the four leaves
// (kuo_toa_pen, glyph_chamber, aboleth_thralls, coral_reliquary) all
// reach the boss. Together with the no-merge invariant below, this
// confirms the design intent: four committed paths, not a diamond.
func TestSunkenTempleGraph_FourDistinctPaths(t *testing.T) {
	g := zoneSunkenTempleGraph()
	for _, leaf := range []string{
		"sunken_temple.kuo_toa_pen",
		"sunken_temple.glyph_chamber",
		"sunken_temple.aboleth_thralls",
		"sunken_temple.coral_reliquary",
	} {
		if !reachable(g, leaf, "sunken_temple.boss") {
			t.Errorf("%s unreachable to boss", leaf)
		}
	}
}

// TestSunkenTempleGraph_NoMidPathMerge ensures no node other than the
// boss has more than one incoming edge. If a future edit collapses the
// two subtrees into a converging diamond, this test fails — that's the
// signal to either rename the zone's shape comment or re-author.
func TestSunkenTempleGraph_NoMidPathMerge(t *testing.T) {
	g := zoneSunkenTempleGraph()
	incoming := map[string]int{}
	for _, outs := range g.Edges {
		for _, e := range outs {
			incoming[e.To]++
		}
	}
	for id, n := range g.Nodes {
		if n.IsBoss {
			continue
		}
		if incoming[id] > 1 {
			t.Errorf("node %q has %d incoming edges, want ≤1 (no mid-path merge)", id, incoming[id])
		}
	}
	// Boss intentionally has 4 incoming edges (one per leaf).
	if incoming["sunken_temple.boss"] != 4 {
		t.Errorf("boss incoming = %d, want 4", incoming["sunken_temple.boss"])
	}
}

func TestSunkenTempleGraph_LockKindCoverage(t *testing.T) {
	g := zoneSunkenTempleGraph()
	kinds := map[ZoneEdgeLockKind]bool{}
	for _, outs := range g.Edges {
		for _, e := range outs {
			kinds[e.Lock] = true
		}
	}
	// Sunken Temple deliberately exercises Perception + StatCheck +
	// LockNone in one zone.
	for _, k := range []ZoneEdgeLockKind{LockNone, LockPerception, LockStatCheck} {
		if !kinds[k] {
			t.Errorf("missing lock kind %s — variety check", k)
		}
	}
}
