/*
 *
 * 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

import (
	"strconv"
	"sync"
	"testing"
	"time"

	"google.golang.org/grpc/internal/grpctest"
)

const (
	testCacheTimeout = 100 * time.Millisecond
)

type s struct {
	grpctest.Tester
}

func Test(t *testing.T) {
	grpctest.RunSubTests(t, s{})
}

func (c *TimeoutCache) getForTesting(key interface{}) (*cacheEntry, bool) {
	c.mu.Lock()
	defer c.mu.Unlock()
	r, ok := c.cache[key]
	return r, ok
}

// TestCacheExpire attempts to add an entry to the cache and verifies that it
// was added successfully. It then makes sure that on timeout, it's removed and
// the associated callback is called.
func (s) TestCacheExpire(t *testing.T) {
	const k, v = 1, "1"
	c := NewTimeoutCache(testCacheTimeout)

	callbackChan := make(chan struct{})
	c.Add(k, v, func() { close(callbackChan) })

	if gotV, ok := c.getForTesting(k); !ok || gotV.item != v {
		t.Fatalf("After Add(), before timeout, from cache got: %v, %v, want %v, %v", gotV.item, ok, v, true)
	}

	select {
	case <-callbackChan:
	case <-time.After(testCacheTimeout * 2):
		t.Fatalf("timeout waiting for callback")
	}

	if _, ok := c.getForTesting(k); ok {
		t.Fatalf("After Add(), after timeout, from cache got: _, %v, want _, %v", ok, false)
	}
}

// TestCacheRemove attempts to remove an existing entry from the cache and
// verifies that the entry is removed and the associated callback is not
// invoked.
func (s) TestCacheRemove(t *testing.T) {
	const k, v = 1, "1"
	c := NewTimeoutCache(testCacheTimeout)

	callbackChan := make(chan struct{})
	c.Add(k, v, func() { close(callbackChan) })

	if got, ok := c.getForTesting(k); !ok || got.item != v {
		t.Fatalf("After Add(), before timeout, from cache got: %v, %v, want %v, %v", got.item, ok, v, true)
	}

	time.Sleep(testCacheTimeout / 2)

	gotV, gotOK := c.Remove(k)
	if !gotOK || gotV != v {
		t.Fatalf("After Add(), before timeout, Remove() got: %v, %v, want %v, %v", gotV, gotOK, v, true)
	}

	if _, ok := c.getForTesting(k); ok {
		t.Fatalf("After Add(), before timeout, after Remove(), from cache got: _, %v, want _, %v", ok, false)
	}

	select {
	case <-callbackChan:
		t.Fatalf("unexpected callback after retrieve")
	case <-time.After(testCacheTimeout * 2):
	}
}

// TestCacheClearWithoutCallback attempts to clear all entries from the cache
// and verifies that the associated callbacks are not invoked.
func (s) TestCacheClearWithoutCallback(t *testing.T) {
	var values []string
	const itemCount = 3
	for i := 0; i < itemCount; i++ {
		values = append(values, strconv.Itoa(i))
	}
	c := NewTimeoutCache(testCacheTimeout)

	done := make(chan struct{})
	defer close(done)
	callbackChan := make(chan struct{}, itemCount)

	for i, v := range values {
		callbackChanTemp := make(chan struct{})
		c.Add(i, v, func() { close(callbackChanTemp) })
		go func() {
			select {
			case <-callbackChanTemp:
				callbackChan <- struct{}{}
			case <-done:
			}
		}()
	}

	for i, v := range values {
		if got, ok := c.getForTesting(i); !ok || got.item != v {
			t.Fatalf("After Add(), before timeout, from cache got: %v, %v, want %v, %v", got.item, ok, v, true)
		}
	}

	time.Sleep(testCacheTimeout / 2)
	c.Clear(false)

	for i := range values {
		if _, ok := c.getForTesting(i); ok {
			t.Fatalf("After Add(), before timeout, after Remove(), from cache got: _, %v, want _, %v", ok, false)
		}
	}

	select {
	case <-callbackChan:
		t.Fatalf("unexpected callback after Clear")
	case <-time.After(testCacheTimeout * 2):
	}
}

// TestCacheClearWithCallback attempts to clear all entries from the cache and
// verifies that the associated callbacks are invoked.
func (s) TestCacheClearWithCallback(t *testing.T) {
	var values []string
	const itemCount = 3
	for i := 0; i < itemCount; i++ {
		values = append(values, strconv.Itoa(i))
	}
	c := NewTimeoutCache(time.Hour)

	testDone := make(chan struct{})
	defer close(testDone)

	var wg sync.WaitGroup
	wg.Add(itemCount)
	for i, v := range values {
		callbackChanTemp := make(chan struct{})
		c.Add(i, v, func() { close(callbackChanTemp) })
		go func() {
			defer wg.Done()
			select {
			case <-callbackChanTemp:
			case <-testDone:
			}
		}()
	}

	allGoroutineDone := make(chan struct{}, itemCount)
	go func() {
		wg.Wait()
		close(allGoroutineDone)
	}()

	for i, v := range values {
		if got, ok := c.getForTesting(i); !ok || got.item != v {
			t.Fatalf("After Add(), before timeout, from cache got: %v, %v, want %v, %v", got.item, ok, v, true)
		}
	}

	time.Sleep(testCacheTimeout / 2)
	c.Clear(true)

	for i := range values {
		if _, ok := c.getForTesting(i); ok {
			t.Fatalf("After Add(), before timeout, after Remove(), from cache got: _, %v, want _, %v", ok, false)
		}
	}

	select {
	case <-allGoroutineDone:
	case <-time.After(testCacheTimeout * 2):
		t.Fatalf("timeout waiting for all callbacks")
	}
}

// TestCacheRetrieveTimeoutRace simulates the case where an entry's timer fires
// around the same time that Remove() is called for it. It verifies that there
// is no deadlock.
func (s) TestCacheRetrieveTimeoutRace(t *testing.T) {
	c := NewTimeoutCache(time.Nanosecond)

	done := make(chan struct{})
	go func() {
		for i := 0; i < 1000; i++ {
			// Add starts a timer with 1 ns timeout, then remove will race
			// with the timer.
			c.Add(i, strconv.Itoa(i), func() {})
			c.Remove(i)
		}
		close(done)
	}()

	select {
	case <-time.After(time.Second):
		t.Fatalf("Test didn't finish within 1 second. Deadlock")
	case <-done:
	}
}
