package notification

// Kind constants name every supported notification kind. The implementation // trims the README §10 catalog to the set with active producers in
// the codebase; further kinds (`game.*`, `mail.dead_lettered`) require
// an additive change here together with a producer.
const (
	KindLobbyInviteReceived = "lobby.invite.received"
	KindLobbyInviteRevoked = "lobby.invite.revoked"
	KindLobbyApplicationSubmitted = "lobby.application.submitted"
	KindLobbyApplicationApproved = "lobby.application.approved"
	KindLobbyApplicationRejected = "lobby.application.rejected"
	KindLobbyMembershipRemoved = "lobby.membership.removed"
	KindLobbyMembershipBlocked = "lobby.membership.blocked"
	KindLobbyRaceNameRegistered = "lobby.race_name.registered"
	KindLobbyRaceNamePending = "lobby.race_name.pending"
	KindLobbyRaceNameExpired = "lobby.race_name.expired"
	KindRuntimeImagePullFailed = "runtime.image_pull_failed"
	KindRuntimeContainerStartFailed = "runtime.container_start_failed"
	KindRuntimeStartConfigInvalid = "runtime.start_config_invalid"
	KindGameTurnReady = "game.turn.ready"
	KindGamePaused = "game.paused"
	KindDiplomailReceived = "diplomail.message.received"
)

// CatalogEntry describes the per-kind delivery policy: which channels
// fan out and whether the kind targets the platform admin recipient
// instead of per-user accounts.
type CatalogEntry struct {
	// Channels lists the channels this kind fans out to, in the order
	// rows are materialised in `notification_routes`. The closed set is
	// {`push`, `email`}.
	Channels []string

	// Admin reports whether the email channel targets the configured
	// admin recipient (`BACKEND_NOTIFICATION_ADMIN_EMAIL`) rather than
	// per-user accounts. Admin-targeted kinds carry an empty Recipients
	// slice on the producer side.
	Admin bool

	// MailTemplateID is the template_id passed to `mail.EnqueueTemplate`
	// for email routes. The catalog uses the kind itself by convention,
	// matching `mail.TemplateLoginCode`'s use of `auth.login_code`.
	MailTemplateID string
}

// catalog maps each supported kind to its delivery policy. The map is
// queried by Submit and by the dispatcher worker; producers do not
// inspect it directly.
var catalog = map[string]CatalogEntry{
	KindLobbyInviteReceived: {
		Channels: []string{ChannelPush, ChannelEmail},
		MailTemplateID: KindLobbyInviteReceived,
	},
	KindLobbyInviteRevoked: {
		Channels: []string{ChannelPush},
	},
	KindLobbyApplicationSubmitted: {
		Channels: []string{ChannelPush},
	},
	KindLobbyApplicationApproved: {
		Channels: []string{ChannelPush, ChannelEmail},
		MailTemplateID: KindLobbyApplicationApproved,
	},
	KindLobbyApplicationRejected: {
		Channels: []string{ChannelPush, ChannelEmail},
		MailTemplateID: KindLobbyApplicationRejected,
	},
	KindLobbyMembershipRemoved: {
		Channels: []string{ChannelPush, ChannelEmail},
		MailTemplateID: KindLobbyMembershipRemoved,
	},
	KindLobbyMembershipBlocked: {
		Channels: []string{ChannelPush, ChannelEmail},
		MailTemplateID: KindLobbyMembershipBlocked,
	},
	KindLobbyRaceNameRegistered: {
		Channels: []string{ChannelPush},
	},
	KindLobbyRaceNamePending: {
		Channels: []string{ChannelPush, ChannelEmail},
		MailTemplateID: KindLobbyRaceNamePending,
	},
	KindLobbyRaceNameExpired: {
		Channels: []string{ChannelPush},
	},
	KindRuntimeImagePullFailed: {
		Channels: []string{ChannelEmail},
		Admin: true,
		MailTemplateID: KindRuntimeImagePullFailed,
	},
	KindRuntimeContainerStartFailed: {
		Channels: []string{ChannelEmail},
		Admin: true,
		MailTemplateID: KindRuntimeContainerStartFailed,
	},
	KindRuntimeStartConfigInvalid: {
		Channels: []string{ChannelEmail},
		Admin: true,
		MailTemplateID: KindRuntimeStartConfigInvalid,
	},
	KindGameTurnReady: {
		Channels: []string{ChannelPush},
	},
	KindGamePaused: {
		Channels: []string{ChannelPush},
	},
	KindDiplomailReceived: {
		Channels: []string{ChannelPush},
	},
}

// LookupCatalog returns the per-kind policy and a boolean reporting
// whether the kind exists. Callers (Submit, Worker) branch on the
// boolean rather than receiving a sentinel error.
func LookupCatalog(kind string) (CatalogEntry, bool) {
	entry, ok := catalog[kind]
	return entry, ok
}

// SupportedKinds returns the closed kind set in deterministic order.
// The function exists to back tests and the migration CHECK constraint
// audit; it is not on the hot path.
func SupportedKinds() []string {
	return []string{
		KindLobbyInviteReceived,
		KindLobbyInviteRevoked,
		KindLobbyApplicationSubmitted,
		KindLobbyApplicationApproved,
		KindLobbyApplicationRejected,
		KindLobbyMembershipRemoved,
		KindLobbyMembershipBlocked,
		KindLobbyRaceNameRegistered,
		KindLobbyRaceNamePending,
		KindLobbyRaceNameExpired,
		KindRuntimeImagePullFailed,
		KindRuntimeContainerStartFailed,
		KindRuntimeStartConfigInvalid,
		KindGameTurnReady,
		KindGamePaused,
		KindDiplomailReceived,
	}
}
