/*
 * Copyright 2019 gRPC authors.
 *
 * Licensed 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 cache implements caches to be used in gRPC.
package cache

import (
	"sync"
	"time"
)

type cacheEntry struct {
	item interface{}
	// Note that to avoid deadlocks (potentially caused by lock ordering),
	// callback can only be called without holding cache's mutex.
	callback func()
	timer    *time.Timer
	// deleted is set to true in Remove() when the call to timer.Stop() fails.
	// This can happen when the timer in the cache entry fires around the same
	// time that timer.stop() is called in Remove().
	deleted bool
}

// TimeoutCache is a cache with items to be deleted after a timeout.
type TimeoutCache struct {
	mu      sync.Mutex
	timeout time.Duration
	cache   map[interface{}]*cacheEntry
}

// NewTimeoutCache creates a TimeoutCache with the given timeout.
func NewTimeoutCache(timeout time.Duration) *TimeoutCache {
	return &TimeoutCache{
		timeout: timeout,
		cache:   make(map[interface{}]*cacheEntry),
	}
}

// Add adds an item to the cache, with the specified callback to be called when
// the item is removed from the cache upon timeout. If the item is removed from
// the cache using a call to Remove before the timeout expires, the callback
// will not be called.
//
// If the Add was successful, it returns (newly added item, true). If there is
// an existing entry for the specified key, the cache entry is not be updated
// with the specified item and it returns (existing item, false).
func (c *TimeoutCache) Add(key, item interface{}, callback func()) (interface{}, bool) {
	c.mu.Lock()
	defer c.mu.Unlock()
	if e, ok := c.cache[key]; ok {
		return e.item, false
	}

	entry := &cacheEntry{
		item:     item,
		callback: callback,
	}
	entry.timer = time.AfterFunc(c.timeout, func() {
		c.mu.Lock()
		if entry.deleted {
			c.mu.Unlock()
			// Abort the delete since this has been taken care of in Remove().
			return
		}
		delete(c.cache, key)
		c.mu.Unlock()
		entry.callback()
	})
	c.cache[key] = entry
	return item, true
}

// Remove the item with the key from the cache.
//
// If the specified key exists in the cache, it returns (item associated with
// key, true) and the callback associated with the item is guaranteed to be not
// called. If the given key is not found in the cache, it returns (nil, false)
func (c *TimeoutCache) Remove(key interface{}) (item interface{}, ok bool) {
	c.mu.Lock()
	defer c.mu.Unlock()
	entry, ok := c.removeInternal(key)
	if !ok {
		return nil, false
	}
	return entry.item, true
}

// removeInternal removes and returns the item with key.
//
// caller must hold c.mu.
func (c *TimeoutCache) removeInternal(key interface{}) (*cacheEntry, bool) {
	entry, ok := c.cache[key]
	if !ok {
		return nil, false
	}
	delete(c.cache, key)
	if !entry.timer.Stop() {
		// If stop was not successful, the timer has fired (this can only happen
		// in a race). But the deleting function is blocked on c.mu because the
		// mutex was held by the caller of this function.
		//
		// Set deleted to true to abort the deleting function. When the lock is
		// released, the delete function will acquire the lock, check the value
		// of deleted and return.
		entry.deleted = true
	}
	return entry, true
}

// Clear removes all entries, and runs the callbacks if runCallback is true.
func (c *TimeoutCache) Clear(runCallback bool) {
	var entries []*cacheEntry
	c.mu.Lock()
	for key := range c.cache {
		if e, ok := c.removeInternal(key); ok {
			entries = append(entries, e)
		}
	}
	c.mu.Unlock()

	if !runCallback {
		return
	}

	// removeInternal removes entries from cache, and also stops the timer, so
	// the callback is guaranteed to be not called. If runCallback is true,
	// manual execute all callbacks.
	for _, entry := range entries {
		entry.callback()
	}
}
