package resource

import (
	"sync"

	"k8s.io/apimachinery/pkg/runtime/schema"
)

//rancherTypes is a set of all types generated by rancher
//clusterScopedTypes is a set of all types that have been added by a clusterScoped handler
var (
	rancherTypes = struct {
		sync.RWMutex
		m map[schema.GroupVersionResource]bool
	}{m: make(map[schema.GroupVersionResource]bool)}

	clusterScopedTypes = struct {
		sync.RWMutex
		m map[schema.GroupVersionResource]bool
	}{m: make(map[schema.GroupVersionResource]bool)}
)

//Get returns a copy of the set of rancherTypes
func Get() map[schema.GroupVersionResource]bool {
	rancherTypes.RLock()
	defer rancherTypes.RUnlock()
	targetMap := make(map[schema.GroupVersionResource]bool, len(rancherTypes.m))
	for key, value := range rancherTypes.m {
		targetMap[key] = value
	}
	return targetMap
}

func GetClusterScopedTypes() map[schema.GroupVersionResource]bool {
	clusterScopedTypes.Lock()
	defer clusterScopedTypes.Unlock()
	targetMap := make(map[schema.GroupVersionResource]bool, len(clusterScopedTypes.m))
	for key, value := range clusterScopedTypes.m {
		targetMap[key] = value
	}
	return targetMap
}

//Put adds an object to the set and panic on collision
func Put(key schema.GroupVersionResource) {
	rancherTypes.Lock()
	defer rancherTypes.Unlock()
	_, exists := rancherTypes.m[key]
	if exists {
		//only used in an init function
		panic("key exists in rancherTypes")
	}
	rancherTypes.m[key] = true
}

//PutClusterScoped adds a object that contains a cluster scoped handler to the set
func PutClusterScoped(key schema.GroupVersionResource) {
	clusterScopedTypes.Lock()
	defer clusterScopedTypes.Unlock()
	clusterScopedTypes.m[key] = true
}
