package router

import "testing"

// The three utterances from the 2026-08-07 week on the box that no local source
// could answer and three different local sources claimed anyway. Stage 0 has to
// say which side of the boundary they are on, because by the time the chain is
// walking, the only thing separating them from a weather forecast is a cosine.
func TestAWorldQuestionNamesTheWorld(t *testing.T) {
	cases := []struct {
		utterance string
		rule      string
	}{
		{"что такое TCP?", "definition-query"},
		{"кто такой Линус Торвальдс?", "definition-query"},
		{"что такая мембрана", "definition-query"},
		{"кто такая Ада Лавлейс?", "definition-query"},
		{"what is TCP?", "definition-query"},
		{"сколько будет 17 на 23?", "arithmetic-query"},
		{"посчитай 2+2", "arithmetic-query"},
		{"сколько будет 5 умножить на 6", "arithmetic-query"},
		{"какая последняя версия Go?", "public-current-version"},
	}
	for _, c := range cases {
		dec, rule, ok := matchWorldQuery(c.utterance)
		if !ok {
			t.Errorf("%q: no world rule claimed it", c.utterance)
			continue
		}
		if rule != c.rule {
			t.Errorf("%q: claimed by %q, want %q", c.utterance, rule, c.rule)
		}
		if dec.Intent != IntentQuery {
			t.Errorf("%q: intent %q, want query", c.utterance, dec.Intent)
		}
		if dec.Source != SourceWorld {
			t.Errorf("%q: source %q, want %q", c.utterance, dec.Source, SourceWorld)
		}
	}
}

// The frame has to be the whole opening or the rule is reading somebody else's
// sentence. Every case here contains a world-question shape and is not one.
func TestAWorldRuleDeclinesWhatIsNotItsShape(t *testing.T) {
	cases := []struct {
		utterance string
		why       string
	}{
		{"напомни узнать что такое TCP", "a reminder that happens to quote the frame"},
		{"запиши что такое TCP", "a capture that happens to quote the frame"},
		{"сколько будет гостей", "an ask with no number is not arithmetic"},
		{"что у меня сегодня?", "his agenda, and the agenda rules own it"},
		{"кто там?", "not the frame"},
		{"посчитай расходы", "no number, so the money source keeps it"},
	}
	for _, c := range cases {
		if _, rule, ok := matchWorldQuery(c.utterance); ok {
			t.Errorf("%q: claimed by %q, want no claim — %s", c.utterance, rule, c.why)
		}
	}
}

// The destination is advice about who may guess, never a filled slot. A rule
// that quietly captured the topic would change what every source below reads.
func TestNamingTheWorldFillsNoSlot(t *testing.T) {
	dec, _, ok := matchWorldQuery("что такое TCP?")
	if !ok {
		t.Fatal("definition-query did not claim it")
	}
	if dec.Slots.Text != "" || dec.Slots.HasTime || dec.Slots.HasFn || dec.Slots.HasKey {
		t.Errorf("slots = %+v, want none filled", dec.Slots)
	}
	if dec.Confidence != 1.0 {
		t.Errorf("confidence = %v, want 1.0 for a stage-0 match", dec.Confidence)
	}
}

func matchWorldQuery(utterance string) (Decision, string, bool) {
	for _, g := range WorldQueryGrammars() {
		if dec, _, ok := g.Evaluate(utterance); ok {
			return dec, g.Name, true
		}
	}
	return Decision{}, "", false
}
