// Copyright 2016 The Vanadium 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 leveldb

import (
	"fmt"
	"io/ioutil"
	"math"
	"math/rand"
	"testing"

	"v.io/x/ref/services/syncbase/store/transactions"
)

func TestWithNoData(t *testing.T) {
	bs, cleanup := newBatchStore()
	defer cleanup()

	// New db with no data added.

	byteCount := bs.filesystemBytes()
	if byteCount != 0 {
		t.Errorf("Wanted zero byteCount for new database. Got %d", byteCount)
	}

	fileCount := bs.fileCount()
	if fileCount != 0 {
		t.Errorf("Got %d files from fileCount(), want 0", fileCount)
	}

	fileCounts, fileMBs, readMBs, writeMBs, err := bs.stats()
	if err != nil {
		t.Errorf("Problem getting stats: %v", err)
	}
	if len(fileCounts) != 0 {
		t.Errorf("Got %d levels, want 0", len(fileCounts))
	}
	if sum(fileCounts) != 0 {
		t.Errorf("Got %d files from stats(), want 0", sum(fileCounts))
	}
	if sum(fileMBs) != 0 {
		t.Errorf("Got %d MB files, want 0", sum(fileMBs))
	}
	if sum(readMBs) != 0 {
		t.Errorf("Got %d MB of reads, want 0", sum(readMBs))
	}
	if sum(writeMBs) != 0 {
		t.Errorf("Got %d MB of writes, want 0", sum(writeMBs))
	}
}

func TestWithLotsOfData(t *testing.T) {
	bs, cleanup := newBatchStore()
	defer cleanup()

	keys := write100MB(bs)

	val, err := bs.Get(keys[0], nil)
	if err != nil {
		t.Errorf("Problem reading from database: %v", err)
	}
	if len(val) != 100*1024 {
		t.Errorf(`Got %d, wanted %d`, len(val), 100*1024)
	}

	// Assume at least half the 100 MB of data made it out to level files.
	byteCount := bs.filesystemBytes()
	if byteCount < 50*1024*1024 {
		t.Errorf("Wanted more than a kB. Got %d B", byteCount)
	}

	// According to https://rawgit.com/google/leveldb/master/doc/impl.html
	// the files are of size 2 MB, so because we have writen 100 MB we
	// expect that eventually that will be 50 files.  But let's be
	// conservative and assume only half of the data has made it out to the
	// level files.
	fileCount := bs.fileCount()
	if fileCount < 25 {
		t.Errorf("Got %d files from fileCount(), want 10 or more", fileCount)
	}

	fileCountsFromStats, fileMBs, readMBs, writeMBs, err := bs.stats()
	if err != nil {
		t.Errorf("Problem getting stats: %v", err)
	}

	// For 100 MB of data, we expect at least two levels of files.
	if len(fileCountsFromStats) < 2 {
		t.Errorf("Got %d levels, want 2 or more", len(fileCountsFromStats))
	}
	// We previously got this a different way.  Let's make sure the two ways
	// match.
	if sum(fileCountsFromStats) != fileCount {
		t.Errorf("Got %d files, want %d", sum(fileCountsFromStats), fileCount)
	}
	// We also previously got this a different way.  Let's make sure the two
	// ways match, at least approximately.
	totFileBytes := uint64(sum(fileMBs)) * 1024 * 1024
	if !approxEquals(totFileBytes, byteCount) {
		t.Errorf("Got %d B of files, want approximately %s B",
			totFileBytes, byteCount)
	}
	// As LevelDB does compression, we assume it has to read a significant
	// amount from the file system.
	if sum(readMBs) < 10 {
		t.Errorf("Got %d MB of reads, want 1 MB or more", sum(readMBs))
	}
	// For writing, we have the initial writing plus extra writing for
	// compaction.
	if sum(writeMBs) < 60 {
		t.Errorf("Got %d MB of writes, want 50 MB or more", sum(writeMBs))
	}
}

// True if within 10%.
func approxEquals(a, b uint64) bool {
	diff := math.Abs(float64(a) - float64(b))
	mean := float64(a+b) / 2.0
	return diff/mean < 0.1
}

func newBatchStore() (bs *db, cleanup func()) {
	path, err := ioutil.TempDir("", "syncbase_leveldb")
	if err != nil {
		panic(err)
	}
	bs, err = openBatchStore(path, OpenOptions{CreateIfMissing: true, ErrorIfExists: true})
	if err != nil {
		panic(err)
	}
	cleanup = func() {
		err := bs.Close()
		if err != nil {
			panic(err)
		}
		err = Destroy(path)
		if err != nil {
			panic(err)
		}
	}
	return
}

// Write 10 bytes each to 1024 keys, returning keys written.
func write10kB(bs transactions.BatchStore) (keys [][]byte) {
	tenB := make([]byte, 10)

	// Write 1024 X 10 B  (10 kB).
	for i := 0; i < 1024; i++ {
		rand.Read(tenB) // Randomize so it won't compress.
		key := []byte(fmt.Sprintf("foo-%d", i))
		err := bs.WriteBatch(transactions.WriteOp{
			T:     transactions.PutOp,
			Key:   key,
			Value: tenB,
		})
		if err != nil {
			panic(err)
		}
		keys = append(keys, key)
	}
	return
}

// Write 100 kB each to 1024 keys, returning keys written.
func write100MB(bs transactions.BatchStore) (keys [][]byte) {
	hundredKB := make([]byte, 100*1024)

	// Write 1024 X 100 KB  (100 MB).
	for i := 0; i < 1024; i++ {
		rand.Read(hundredKB) // Randomize so it won't compress.
		key := []byte(fmt.Sprintf("foo-%d", i))
		err := bs.WriteBatch(transactions.WriteOp{
			T:     transactions.PutOp,
			Key:   key,
			Value: hundredKB,
		})
		if err != nil {
			panic(err)
		}
		keys = append(keys, key)
	}
	return
}

func sum(xs []int) (result int) {
	for _, x := range xs {
		result += x
	}
	return
}
