/*
 * 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 any
	// 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[any]*cacheEntry
}

// NewTimeoutCache creates a TimeoutCache with the given timeout.
func NewTimeoutCache(timeout time.Duration) *TimeoutCache {
	return &TimeoutCache{
		timeout: timeout,
		cache:   make(map[any]*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 any, callback func()) (any, 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 any) (item any, 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 any) (*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()
	}
}

// Len returns the number of entries in the cache.
func (c *TimeoutCache) Len() int {
	c.mu.Lock()
	defer c.mu.Unlock()
	return len(c.cache)
}
