// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package cache

import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"math/rand"
	"os"
	"runtime"
	"sync"
	"sync/atomic"
	"testing"
	"time"
)

// hammerThread is a way for users to configure specific loads on the cache.
// the times are not maintained precisely due to the fact that the time it
// takes to perform an operation on the cache is assumed to be zero.
type hammerThread struct {
	// ReadsPerSec sets the mean rate of read operations for this thread in
	// reads per second
	ReadsPerSec float64 `json:"rps"`
	// ReadTime sets the mean time to hold on to a file for before closing.
	ReadTime float64 `json:"read_time"`
	// WritesPerSec sets the mean rate of write operations for this thread in
	// reads per second.
	WritesPerSec float64 `json:"wps"`
	// Duration is the number of seconds this thread should run for.
	Duration float64 `json:"duration"`
}

type hammerProc struct {
	Threads []hammerThread `json:"threads"`
}

type fuzzerProc struct {
	hammerProc
	cache *FileCache
}

type fuzzKey string

func (f fuzzKey) Hash() string {
	return string(f)
}

type cacheFuzzer struct {
	cachePath string
	size      uint64
	procs     []fuzzerProc
	// TODO: Figure out if write contention is making things slow and bucket
	// the keys so that a lock only has to be obtained for the particular part
	// of the map being used.
	recordLock sync.RWMutex
	record     map[string]string
	// These need to be updated atomically.
	totalMisses uint64
	totalTries  uint64
	totalWrites uint64
	writeFails  uint64
	// Makes sure we wait on all threads.
	wg sync.WaitGroup
}

func newCacheFuzzer(config string, cachePath string, size uint64) (*cacheFuzzer, error) {
	file := bytes.NewBufferString(config)
	var out cacheFuzzer
	out.cachePath = cachePath
	out.size = size
	dec := json.NewDecoder(file)
	var procs []hammerProc
	dec.Decode(&procs)
	for _, proc := range procs {
		filecache, err := GetFileCache(cachePath, size)
		if err != nil {
			return nil, err
		}
		out.procs = append(out.procs, fuzzerProc{proc, filecache})
	}
	out.record = make(map[string]string)
	return &out, nil
}

func (c *cacheFuzzer) checkRead(t *testing.T, readTime float64, filecache *FileCache) {
	// Acquire the lock for the minimum amount of time. We want the actual cache
	// read to not be blocked by the lock.
	var key string
	var value string
	foundSample := func() bool {
		c.recordLock.RLock()
		defer func() {
			c.recordLock.RUnlock()
			runtime.Gosched()
		}()
		for k, v := range c.record {
			key, value = k, v
			return true
		}
		return false
	}()
	// Make sure we actually sampled a real key/value pair
	if !foundSample {
		return
	}
	// Now test that the key and value make sense.
	atomic.AddUint64(&c.totalTries, 1)
	ref, err := filecache.Get(fuzzKey(key))
	// Note that if we miss, it was because the file was culled. We don't attempt
	// to test that keys that were never added hit this case.
	if err != nil {
		atomic.AddUint64(&c.totalMisses, 1)
		return
	}
	// Make sure we wait on this to close
	c.wg.Add(1)
	// Now hold on to the file for a random amount of time.
	go func() {
		defer c.wg.Done()
		defer ref.Close()
		sleepRand(readTime)
		data, err := os.ReadFile(ref.String())
		if err != nil {
			t.Errorf("could not read file: %v", err)
		}
		if string(data) != value {
			t.Errorf("could not read file: %v", err)
		}
	}()
}

// Generates a random hex string of 16-bytes with maximal entropy.
// This should give enough enough entropy to ensure that the same
// string is never used twice.
func getRandomString() string {
	out := make([]byte, 16)
	rand.Read(out)
	return hex.EncodeToString(out)
}

// This function shouldn't actually fail but adds new things to the cache
// so that further gets can be tested later.
func (c *cacheFuzzer) checkWrite(t *testing.T, filecache *FileCache) {
	// We want to perform the write without a lock. The only part that should
	// lock is updating the internal data structure we use to keep track of keys.
	key := getRandomString()
	value := getRandomString()
	atomic.AddUint64(&c.totalWrites, 1)
	file, err := filecache.Add(fuzzKey(key), bytes.NewBufferString(value))
	if err != nil {
		t.Errorf("%v", err)
		atomic.AddUint64(&c.writeFails, 1)
		return
	}
	file.Close()
	c.recordLock.Lock()
	defer c.recordLock.Unlock()
	c.record[key] = value
}

// Sleep for a number of random number of seconds with mean 'beta'.
// Entropy is maximized. To get an expected number of operations per
// second of N you can use 1/N as beta to get maximally entropicly timed
// events. The amount of time slept for is returned.
func sleepRand(beta float64) float64 {
	out := rand.ExpFloat64() * beta
	time.Sleep(time.Duration(out * float64(time.Second)))
	return out
}

func (c *cacheFuzzer) fuzzThread(t *testing.T, proc fuzzerProc, thread hammerThread) {
	// lambda is the expected number of operations per second
	lambda := thread.ReadsPerSec + thread.WritesPerSec
	// readProb is the probability that one of our operations will be a read.
	readProb := thread.ReadsPerSec / lambda
	// we need to keep track of the total time we've slept for and die at the end.
	totalTime := 0.0
	for totalTime < thread.Duration {
		totalTime += sleepRand(1.0 / lambda)
		if rand.Float64() < readProb {
			c.checkRead(t, thread.ReadTime, proc.cache)
		} else {
			c.checkWrite(t, proc.cache)
		}
	}
	// Note that checkRead can call c.wg.Add. It is safe for it to call Add as
	// long as it proceeds this Done.
	c.wg.Done()
}

func (c *cacheFuzzer) fuzzProc(t *testing.T, proc fuzzerProc) {
	for _, thread := range proc.Threads {
		c.wg.Add(1)
		go c.fuzzThread(t, proc, thread)
	}
}

func (c *cacheFuzzer) fuzz(t *testing.T) {
	for _, proc := range c.procs {
		c.fuzzProc(t, proc)
	}
	c.wg.Wait()
}

const fuzzConfig = `
[
  {"threads":[
    { "rps": 1000.0, "read_time": 0.000001, "wps": 100.0, "duration": 1.0 },
    { "rps": 2000.0, "read_time": 0.15, "wps": 100.0, "duration": 0.5 },
    { "rps": 10.0, "read_time": 0.001, "wps": 1000.0, "duration": 1.1 },
    { "rps": 5000.0, "read_time": 0.1, "wps": 10.0, "duration": 0.7 }
  ]},
  {"threads":[
    { "rps": 1000.0, "read_time": 0.01, "wps": 100.0, "duration": 1.1 },
    { "rps": 2000.0, "read_time": 0.0001, "wps": 100.0, "duration": 1.2 },
    { "rps": 10.0, "read_time": 0.05, "wps": 1000.0, "duration": 0.3 },
    { "rps": 5000.0, "read_time": 0.001, "wps": 10.0, "duration": 1.3 }
  ]},
  {"threads":[
    { "rps": 1000.0, "read_time": 0.01, "wps": 100.0, "duration": 0.5 },
    { "rps": 2000.0, "read_time": 0.001, "wps": 100.0, "duration": 1.0 },
    { "rps": 10.0, "read_time": 0.05, "wps": 1000.0, "duration": 1.5 },
    { "rps": 5000.0, "read_time": 0.005, "wps": 10.0, "duration": 1.0 }
  ]}
]
`

func TestFileCache(t *testing.T) {
	cachePath := t.TempDir()
	filecache, err := newCacheFuzzer(fuzzConfig, cachePath, 250)
	if err != nil {
		t.Fatalf("%v", err)
	}
	filecache.fuzz(t)
	t.Logf("cache hit/miss ratio: %v:%v", filecache.totalTries-filecache.totalMisses, filecache.totalMisses)
	t.Logf("write success/fail ratio: %v:%v", filecache.totalWrites-filecache.writeFails, filecache.writeFails)
	if err := DeleteCache(cachePath); err != nil {
		t.Error(err)
	}
}
