package router

import (
	"strings"

	"github.com/kami/maven/internal/lexicon"
	"github.com/kami/maven/internal/morph"
)

// transientWords — the states a thing is in for an afternoon, as dictionary
// forms. They used to be prefixes, which is how a prefix list always goes wrong:
// "лаг" matched "лагерь" and "падает" matched nothing else it inflected into.
// morph.SameWord compares the words themselves (Vikunja #528).
//
// Russian aspect pairs are two separate verbs, so a slot lists both where both
// are said. English members have no dictionary here and fall back to exact
// comparison, which is what they had.
var transientWords = []string{
	"медленный", "медленно", "тормозить", "тормоз", "лагать", "лаг",
	"зависать", "зависнуть", "виснуть", "глючить", "барахлить",
	"отваливаться", "отвалиться", "падать", "упасть", "сдохнуть",
	"греться", "перегреваться", "перегреться",
	"slow", "laggy", "stuck", "frozen", "flaky", "broken", "down",
}

// brokenWords — what "не ..." is denying when the sentence is a complaint.
// Dictionary forms, same reason.
var brokenWords = []string{
	"работать", "пахать", "грузить", "грузиться", "открываться",
	"включаться", "коннектиться", "подключаться",
	"work", "load", "connect", "respond",
}

// selfMarkers — the words that make a sentence about him rather than about a
// thing. Their presence turns the test off, because losing a fact he meant to
// store is worse than keeping a complaint: "я сломал руку" is durable, and
// "интернет не работает" is not.
//
// A closed class, so it comes from the lexicon: the first-person pronoun has a
// fixed number of forms and this file was the third place they were typed out
// (Vikunja #528).
var selfMarkers = lexicon.FirstPerson()

// IsTransientComplaint reports whether text observes a passing state of some
// thing rather than recording a fact.
//
// It exists because "сеть какая-то медленная" and "интернет не работает" were
// written to the fact store as `self` rows at confidence 1.00 (Vikunja #481),
// where recall reads them back later as if they were still true. A complaint
// describes a moment; the fact store describes him.
//
// Deterministic, offline, and shaped exactly like IsQuestionShaped: an
// explicit capture verb wins over everything, because "запомни что интернет
// не работает" is an instruction and not a passing remark. A first-person
// marker also turns it off — the test is meant to catch a sentence about a
// thing, and it errs toward storing.
func IsTransientComplaint(text string) bool {
	t := strings.TrimSpace(text)
	if t == "" {
		return false
	}
	toks := planTokens(strings.ToLower(t))
	for _, v := range captureVerbs {
		if hasTok(toks, v) {
			return false
		}
	}
	for _, m := range selfMarkers {
		if hasTok(toks, m) {
			return false
		}
	}
	for _, tok := range toks {
		for _, w := range transientWords {
			if morph.SameWord(tok, w) {
				return true
			}
		}
	}
	// "не" plus a verb of working, in either order of the two tokens that
	// follow it — "не работает" and "не очень работает" both deny the same
	// thing.
	for i, tok := range toks {
		if tok != "не" && tok != "not" && tok != "isn" {
			continue
		}
		for j := i + 1; j < len(toks) && j <= i+2; j++ {
			for _, v := range brokenWords {
				if morph.SameWord(toks[j], v) {
					return true
				}
			}
		}
	}
	return false
}
