/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package zookeeper

import (
	"strings"
	"sync"
)

import (
	"github.com/apache/dubbo-go/config_center"
	"github.com/apache/dubbo-go/remoting"
)

// CacheListener ...
type CacheListener struct {
	keyListeners sync.Map
	rootPath     string
}

// NewCacheListener ...
func NewCacheListener(rootPath string) *CacheListener {
	return &CacheListener{rootPath: rootPath}
}

// AddListener ...
func (l *CacheListener) AddListener(key string, listener config_center.ConfigurationListener) {

	// reference from https://stackoverflow.com/questions/34018908/golang-why-dont-we-have-a-set-datastructure
	// make a map[your type]struct{} like set in java
	listeners, loaded := l.keyListeners.LoadOrStore(key, map[config_center.ConfigurationListener]struct{}{listener: {}})
	if loaded {
		listeners.(map[config_center.ConfigurationListener]struct{})[listener] = struct{}{}
		l.keyListeners.Store(key, listeners)
	}
}

// RemoveListener ...
func (l *CacheListener) RemoveListener(key string, listener config_center.ConfigurationListener) {
	listeners, loaded := l.keyListeners.Load(key)
	if loaded {
		delete(listeners.(map[config_center.ConfigurationListener]struct{}), listener)
	}
}

// DataChange ...
func (l *CacheListener) DataChange(event remoting.Event) bool {
	if event.Content == "" {
		//meanings new node
		return true
	}
	key := l.pathToKey(event.Path)
	if key != "" {
		if listeners, ok := l.keyListeners.Load(key); ok {
			for listener := range listeners.(map[config_center.ConfigurationListener]struct{}) {
				listener.Process(&config_center.ConfigChangeEvent{Key: key, Value: event.Content, ConfigType: event.Action})
			}
			return true
		}
	}
	return false
}

func (l *CacheListener) pathToKey(path string) string {
	return strings.Replace(strings.Replace(path, l.rootPath+"/", "", -1), "/", ".", -1)
}
