package events

import (
	"sort"
	"strings"
	"sync"
)

var defaultNoSubscriberRecordEventObjects = struct {
	sync.RWMutex
	objects map[string]string
}{
	objects: map[string]string{},
}

// RegisterDefaultNoSubscriberRecordEventObjects installs platform or product
// object names whose record events may be skipped when metadata proves no
// record-triggered flow is subscribed. The event kernel owns the outbox filter;
// object ownership is registered by the feature or product that owns the object.
func RegisterDefaultNoSubscriberRecordEventObjects(objects ...string) {
	defaultNoSubscriberRecordEventObjects.Lock()
	defer defaultNoSubscriberRecordEventObjects.Unlock()
	for _, rawObject := range objects {
		object := strings.TrimSpace(rawObject)
		if object == "" {
			continue
		}
		key := strings.ToLower(object)
		if _, ok := defaultNoSubscriberRecordEventObjects.objects[key]; ok {
			continue
		}
		defaultNoSubscriberRecordEventObjects.objects[key] = object
	}
}

func isNoSubscriberRecordEventObject(objectAPIName string) bool {
	object := strings.ToLower(strings.TrimSpace(objectAPIName))
	if object == "" {
		return false
	}
	defaultNoSubscriberRecordEventObjects.RLock()
	defer defaultNoSubscriberRecordEventObjects.RUnlock()
	_, ok := defaultNoSubscriberRecordEventObjects.objects[object]
	return ok
}

func DefaultNoSubscriberRecordEventObjects() []string {
	defaultNoSubscriberRecordEventObjects.RLock()
	defer defaultNoSubscriberRecordEventObjects.RUnlock()
	out := make([]string, 0, len(defaultNoSubscriberRecordEventObjects.objects))
	for _, object := range defaultNoSubscriberRecordEventObjects.objects {
		out = append(out, object)
	}
	sort.Strings(out)
	return out
}

func ResetDefaultNoSubscriberRecordEventObjectsForTest() func() {
	defaultNoSubscriberRecordEventObjects.Lock()
	previous := cloneNoSubscriberRecordEventObjectsLocked()
	defaultNoSubscriberRecordEventObjects.objects = map[string]string{}
	defaultNoSubscriberRecordEventObjects.Unlock()
	return func() {
		defaultNoSubscriberRecordEventObjects.Lock()
		defaultNoSubscriberRecordEventObjects.objects = previous
		defaultNoSubscriberRecordEventObjects.Unlock()
	}
}

func cloneNoSubscriberRecordEventObjectsLocked() map[string]string {
	out := make(map[string]string, len(defaultNoSubscriberRecordEventObjects.objects))
	for key, object := range defaultNoSubscriberRecordEventObjects.objects {
		out[key] = object
	}
	return out
}
