package web

import (
	"strings"
	"testing"

	"pete/internal/storage"
)

// The retreat bulletin — gogobee's newest event type.
//
// The failure this guards against is silent and total: handleAdventureIngest
// answers an unrecognized event_type with 400, and gogobee's sender treats any
// non-2xx as a failure, retries eight times over ~two hours, and then PARKS the
// row forever. So a gogobee that emits `retreat` against a Pete that doesn't
// know the word doesn't log an error anyone reads — it just quietly drops every
// retreat the realm ever files. Pete has to learn the word first, and this test
// is what says he has.
func TestAdventureIngest_AcceptsRetreat(t *testing.T) {
	const token = "s3cret-token"
	s, posted := newAdvServer(t, token)

	f := AdvFact{
		GUID: "retreat:abc:1000", EventType: "retreat", Tier: "bulletin",
		Actors: []string{"Brannigan"}, Subject: "Brannigan",
		Zone: "the Underforge", Level: 12, Count: 3, Outcome: "retreated",
		OccurredAt: 1000,
	}
	if rw := postFact(t, s, token, f); rw.Code != 200 {
		t.Fatalf("ingest status = %d body=%s — Pete rejected a retreat, so gogobee will "+
			"retry it eight times and park it forever", rw.Code, rw.Body.String())
	}

	got, err := storage.GetStoryByGUID("retreat:abc:1000")
	if err != nil || got == nil {
		t.Fatalf("retreat was accepted but not stored: %v", err)
	}
	// It has to actually say what happened, in Pete's voice, using only the
	// supplied facts.
	body := got.Headline + " " + got.Lede
	for _, want := range []string{"Brannigan", "the Underforge"} {
		if !strings.Contains(body, want) {
			t.Errorf("rendered retreat is missing %q: %q", want, body)
		}
	}
	if !strings.Contains(got.Lede, "3 days in") {
		t.Errorf("the day count never made it into the copy: %q", got.Lede)
	}
	// Bulletin, not priority: a retreat goes in the daily digest, it does not
	// interrupt the room. Pete announcing every failed run live would be a
	// firehose — and an unkind one.
	if len(*posted) != 0 {
		t.Errorf("a bulletin was posted live: %+v", *posted)
	}
}
