

package canaryconfigmgr

import (
	"context"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/fission/fission/pkg/cache"
)

type (
	canaryConfigCancelFuncMap struct {
		cache *cache.Cache // map[metadataKey]*context.Context
	}

	// metav1.ObjectMeta is not hashable, so we make a hashable copy
	// of the subset of its fields that are identifiable.
	metadataKey struct {
		Name      string
		Namespace string
	}

	CanaryProcessingInfo struct {
		CancelFunc *context.CancelFunc
		Ticker     *time.Ticker
	}
)

func makecanaryConfigCancelFuncMap() *canaryConfigCancelFuncMap {
	return &canaryConfigCancelFuncMap{
		cache: cache.MakeCache(0, 0),
	}
}

func keyFromMetadata(m *metav1.ObjectMeta) metadataKey {
	return metadataKey{
		Name:      m.Name,
		Namespace: m.Namespace,
	}
}

func (cancelFuncMap *canaryConfigCancelFuncMap) lookup(f *metav1.ObjectMeta) (*CanaryProcessingInfo, error) {
	mk := keyFromMetadata(f)
	item, err := cancelFuncMap.cache.Get(mk)
	if err != nil {
		return nil, err
	}
	value := item.(*CanaryProcessingInfo)
	return value, nil
}

func (cancelFuncMap *canaryConfigCancelFuncMap) assign(f *metav1.ObjectMeta, value *CanaryProcessingInfo) error {
	mk := keyFromMetadata(f)
	_, err := cancelFuncMap.cache.Set(mk, value)
	return err
}

func (cancelFuncMap *canaryConfigCancelFuncMap) remove(f *metav1.ObjectMeta) error {
	mk := keyFromMetadata(f)
	return cancelFuncMap.cache.Delete(mk)
}
