package manager

import (
	"code.justin.tv/systems/sandstorm/internal/secret"
)

// SecretChangeset provides function to be used in registestered callback methods
// to help build the custom logic in callback.
type SecretChangeset interface {

	// Check if any of the registered secret have been updated
	SecretsHaveChanged() bool

	// Check if "secretName" has been updated
	SecretHasBeenUpdated(secretName string) bool

	// Get updated at value for the updated secret
	GetSecretUpdatedAt(secretName string) int64
}

// ClearSecretCallbacks removes all secret callbacks
func (m *Manager) ClearSecretCallbacks() {
	m.secretCallbacksLock.Lock()
	defer m.secretCallbacksLock.Unlock()

	m.secretCallbacks = make(map[string][]func(SecretChangeset))
}

// RegisterSecretUpdateCallback registers a callback to be called when a secret
// is updated
func (m *Manager) RegisterSecretUpdateCallback(secretName string, callback func(input SecretChangeset)) {
	m.secretCallbacksLock.Lock()
	defer m.secretCallbacksLock.Unlock()

	callbacks, ok := m.secretCallbacks[secretName]
	if !ok {
		callbacks = make([]func(SecretChangeset), 0, 1)
	}
	m.secretCallbacks[secretName] = append(callbacks, callback)
	return
}

func (m *Manager) triggerSecretUpdateCallbacks(secretName string, updatedAt int64) {
	callbacks, ok := m.secretCallbacks[secretName]
	if !ok {
		return
	}

	for _, cb := range callbacks {
		cb(&secret.Changeset{
			SecretInfo: map[string]int64{
				secretName: updatedAt,
			},
		})
	}
}
