// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENE file.

package leveldb

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"os"
	"path/filepath"
	"sync"
	"testing"

	"github.com/syndtr/goleveldb/leveldb/storage"
	"github.com/syndtr/goleveldb/leveldb/util"
)

const typeShift = 4

var (
	tsErrInvalidFile = errors.New("leveldb.testStorage: invalid file for argument")
	tsErrFileOpen    = errors.New("leveldb.testStorage: file still open")
)

var (
	tsFSEnv   = os.Getenv("GOLEVELDB_USEFS")
	tsTempdir = os.Getenv("GOLEVELDB_TEMPDIR")
	tsKeepFS  = tsFSEnv == "2"
	tsFS      = tsKeepFS || tsFSEnv == "" || tsFSEnv == "1"
	tsMU      = &sync.Mutex{}
	tsNum     = 0
)

type tsOp uint

const (
	tsOpOpen tsOp = iota
	tsOpCreate
	tsOpReplace
	tsOpRemove
	tsOpRead
	tsOpReadAt
	tsOpWrite
	tsOpSync

	tsOpNum
)

type tsLock struct {
	ts *testStorage
	r  util.Releaser
}

func (l tsLock) Release() {
	l.r.Release()
	l.ts.t.Log("I: storage lock released")
}

type tsReader struct {
	tf tsFile
	storage.Reader
}

func (tr tsReader) Read(b []byte) (n int, err error) {
	ts := tr.tf.ts
	ts.countRead(tr.tf.Type())
	if tr.tf.shouldErrLocked(tsOpRead) {
		return 0, errors.New("leveldb.testStorage: emulated read error")
	}
	n, err = tr.Reader.Read(b)
	if err != nil && err != io.EOF {
		ts.t.Errorf("E: read error, num=%d type=%v n=%d: %v", tr.tf.Num(), tr.tf.Type(), n, err)
	}
	return
}

func (tr tsReader) ReadAt(b []byte, off int64) (n int, err error) {
	ts := tr.tf.ts
	ts.countRead(tr.tf.Type())
	if tr.tf.shouldErrLocked(tsOpReadAt) {
		return 0, errors.New("leveldb.testStorage: emulated readAt error")
	}
	n, err = tr.Reader.ReadAt(b, off)
	if err != nil && err != io.EOF {
		ts.t.Errorf("E: readAt error, num=%d type=%v off=%d n=%d: %v", tr.tf.Num(), tr.tf.Type(), off, n, err)
	}
	return
}

func (tr tsReader) Close() (err error) {
	err = tr.Reader.Close()
	tr.tf.close("reader", err)
	return
}

type tsWriter struct {
	tf tsFile
	storage.Writer
}

func (tw tsWriter) Write(b []byte) (n int, err error) {
	if tw.tf.shouldErrLocked(tsOpWrite) {
		return 0, errors.New("leveldb.testStorage: emulated write error")
	}
	n, err = tw.Writer.Write(b)
	if err != nil {
		tw.tf.ts.t.Errorf("E: write error, num=%d type=%v n=%d: %v", tw.tf.Num(), tw.tf.Type(), n, err)
	}
	return
}

func (tw tsWriter) Sync() (err error) {
	ts := tw.tf.ts
	ts.mu.Lock()
	for ts.emuDelaySync&tw.tf.Type() != 0 {
		ts.cond.Wait()
	}
	ts.mu.Unlock()
	if tw.tf.shouldErrLocked(tsOpSync) {
		return errors.New("leveldb.testStorage: emulated sync error")
	}
	err = tw.Writer.Sync()
	if err != nil {
		tw.tf.ts.t.Errorf("E: sync error, num=%d type=%v: %v", tw.tf.Num(), tw.tf.Type(), err)
	}
	return
}

func (tw tsWriter) Close() (err error) {
	err = tw.Writer.Close()
	tw.tf.close("writer", err)
	return
}

type tsFile struct {
	ts *testStorage
	storage.File
}

func (tf tsFile) x() uint64 {
	return tf.Num()<<typeShift | uint64(tf.Type())
}

func (tf tsFile) shouldErr(op tsOp) bool {
	return tf.ts.shouldErr(tf, op)
}

func (tf tsFile) shouldErrLocked(op tsOp) bool {
	tf.ts.mu.Lock()
	defer tf.ts.mu.Unlock()
	return tf.shouldErr(op)
}

func (tf tsFile) checkOpen(m string) error {
	ts := tf.ts
	if writer, ok := ts.opens[tf.x()]; ok {
		if writer {
			ts.t.Errorf("E: cannot %s file, num=%d type=%v: a writer still open", m, tf.Num(), tf.Type())
		} else {
			ts.t.Errorf("E: cannot %s file, num=%d type=%v: a reader still open", m, tf.Num(), tf.Type())
		}
		return tsErrFileOpen
	}
	return nil
}

func (tf tsFile) close(m string, err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	if _, ok := ts.opens[tf.x()]; !ok {
		ts.t.Errorf("E: %s: redudant file closing, num=%d type=%v", m, tf.Num(), tf.Type())
	} else if err == nil {
		ts.t.Logf("I: %s: file closed, num=%d type=%v", m, tf.Num(), tf.Type())
	}
	delete(ts.opens, tf.x())
	if err != nil {
		ts.t.Errorf("E: %s: cannot close file, num=%d type=%v: %v", m, tf.Num(), tf.Type(), err)
	}
}

func (tf tsFile) Open() (r storage.Reader, err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	err = tf.checkOpen("open")
	if err != nil {
		return
	}
	if tf.shouldErr(tsOpOpen) {
		err = errors.New("leveldb.testStorage: emulated open error")
		return
	}
	r, err = tf.File.Open()
	if err != nil {
		if ts.ignoreOpenErr&tf.Type() != 0 {
			ts.t.Logf("I: cannot open file, num=%d type=%v: %v (ignored)", tf.Num(), tf.Type(), err)
		} else {
			ts.t.Errorf("E: cannot open file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
		}
	} else {
		ts.t.Logf("I: file opened, num=%d type=%v", tf.Num(), tf.Type())
		ts.opens[tf.x()] = false
		r = tsReader{tf, r}
	}
	return
}

func (tf tsFile) Create() (w storage.Writer, err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	err = tf.checkOpen("create")
	if err != nil {
		return
	}
	if tf.shouldErr(tsOpCreate) {
		err = errors.New("leveldb.testStorage: emulated create error")
		return
	}
	w, err = tf.File.Create()
	if err != nil {
		ts.t.Errorf("E: cannot create file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
	} else {
		ts.t.Logf("I: file created, num=%d type=%v", tf.Num(), tf.Type())
		ts.opens[tf.x()] = true
		w = tsWriter{tf, w}
	}
	return
}

func (tf tsFile) Replace(newfile storage.File) (err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	err = tf.checkOpen("replace")
	if err != nil {
		return
	}
	if tf.shouldErr(tsOpReplace) {
		err = errors.New("leveldb.testStorage: emulated create error")
		return
	}
	err = tf.File.Replace(newfile.(tsFile).File)
	if err != nil {
		ts.t.Errorf("E: cannot replace file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
	} else {
		ts.t.Logf("I: file replace, num=%d type=%v", tf.Num(), tf.Type())
	}
	return
}

func (tf tsFile) Remove() (err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	err = tf.checkOpen("remove")
	if err != nil {
		return
	}
	if tf.shouldErr(tsOpRemove) {
		err = errors.New("leveldb.testStorage: emulated create error")
		return
	}
	err = tf.File.Remove()
	if err != nil {
		ts.t.Errorf("E: cannot remove file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
	} else {
		ts.t.Logf("I: file removed, num=%d type=%v", tf.Num(), tf.Type())
	}
	return
}

type testStorage struct {
	t *testing.T
	storage.Storage
	closeFn func() error

	mu   sync.Mutex
	cond sync.Cond
	// Open files, true=writer, false=reader
	opens         map[uint64]bool
	emuDelaySync  storage.FileType
	ignoreOpenErr storage.FileType
	readCnt       uint64
	readCntEn     storage.FileType

	emuErr         [tsOpNum]storage.FileType
	emuErrOnce     [tsOpNum]storage.FileType
	emuRandErr     [tsOpNum]storage.FileType
	emuRandErrProb int
	emuErrOnceMap  map[uint64]uint
	emuRandRand    *rand.Rand
}

func (ts *testStorage) shouldErr(tf tsFile, op tsOp) bool {
	if ts.emuErr[op]&tf.Type() != 0 {
		return true
	} else if ts.emuRandErr[op]&tf.Type() != 0 || ts.emuErrOnce[op]&tf.Type() != 0 {
		sop := uint(1) << op
		eop := ts.emuErrOnceMap[tf.x()]
		if eop&sop == 0 && (ts.emuRandRand.Int()%ts.emuRandErrProb == 0 || ts.emuErrOnce[op]&tf.Type() != 0) {
			ts.emuErrOnceMap[tf.x()] = eop | sop
			ts.t.Logf("I: emulated error: file=%d type=%v op=%v", tf.Num(), tf.Type(), op)
			return true
		}
	}
	return false
}

func (ts *testStorage) SetEmuErr(t storage.FileType, ops ...tsOp) {
	ts.mu.Lock()
	for _, op := range ops {
		ts.emuErr[op] = t
	}
	ts.mu.Unlock()
}

func (ts *testStorage) SetEmuErrOnce(t storage.FileType, ops ...tsOp) {
	ts.mu.Lock()
	for _, op := range ops {
		ts.emuErrOnce[op] = t
	}
	ts.mu.Unlock()
}

func (ts *testStorage) SetEmuRandErr(t storage.FileType, ops ...tsOp) {
	ts.mu.Lock()
	for _, op := range ops {
		ts.emuRandErr[op] = t
	}
	ts.mu.Unlock()
}

func (ts *testStorage) SetEmuRandErrProb(prob int) {
	ts.mu.Lock()
	ts.emuRandErrProb = prob
	ts.mu.Unlock()
}

func (ts *testStorage) DelaySync(t storage.FileType) {
	ts.mu.Lock()
	ts.emuDelaySync |= t
	ts.cond.Broadcast()
	ts.mu.Unlock()
}

func (ts *testStorage) ReleaseSync(t storage.FileType) {
	ts.mu.Lock()
	ts.emuDelaySync &= ^t
	ts.cond.Broadcast()
	ts.mu.Unlock()
}

func (ts *testStorage) ReadCounter() uint64 {
	ts.mu.Lock()
	defer ts.mu.Unlock()
	return ts.readCnt
}

func (ts *testStorage) ResetReadCounter() {
	ts.mu.Lock()
	ts.readCnt = 0
	ts.mu.Unlock()
}

func (ts *testStorage) SetReadCounter(t storage.FileType) {
	ts.mu.Lock()
	ts.readCntEn = t
	ts.mu.Unlock()
}

func (ts *testStorage) countRead(t storage.FileType) {
	ts.mu.Lock()
	if ts.readCntEn&t != 0 {
		ts.readCnt++
	}
	ts.mu.Unlock()
}

func (ts *testStorage) SetIgnoreOpenErr(t storage.FileType) {
	ts.ignoreOpenErr = t
}

func (ts *testStorage) Lock() (r util.Releaser, err error) {
	r, err = ts.Storage.Lock()
	if err != nil {
		ts.t.Logf("W: storage locking failed: %v", err)
	} else {
		ts.t.Log("I: storage locked")
		r = tsLock{ts, r}
	}
	return
}

func (ts *testStorage) Log(str string) {
	ts.t.Log("L: " + str)
	ts.Storage.Log(str)
}

func (ts *testStorage) GetFile(num uint64, t storage.FileType) storage.File {
	return tsFile{ts, ts.Storage.GetFile(num, t)}
}

func (ts *testStorage) GetFiles(t storage.FileType) (ff []storage.File, err error) {
	ff0, err := ts.Storage.GetFiles(t)
	if err != nil {
		ts.t.Errorf("E: get files failed: %v", err)
		return
	}
	ff = make([]storage.File, len(ff0))
	for i, f := range ff0 {
		ff[i] = tsFile{ts, f}
	}
	ts.t.Logf("I: get files, type=0x%x count=%d", int(t), len(ff))
	return
}

func (ts *testStorage) GetManifest() (f storage.File, err error) {
	f0, err := ts.Storage.GetManifest()
	if err != nil {
		if !os.IsNotExist(err) {
			ts.t.Errorf("E: get manifest failed: %v", err)
		}
		return
	}
	f = tsFile{ts, f0}
	ts.t.Logf("I: get manifest, num=%d", f.Num())
	return
}

func (ts *testStorage) SetManifest(f storage.File) error {
	tf, ok := f.(tsFile)
	if !ok {
		ts.t.Error("E: set manifest failed: type assertion failed")
		return tsErrInvalidFile
	} else if tf.Type() != storage.TypeManifest {
		ts.t.Errorf("E: set manifest failed: invalid file type: %s", tf.Type())
		return tsErrInvalidFile
	}
	err := ts.Storage.SetManifest(tf.File)
	if err != nil {
		ts.t.Errorf("E: set manifest failed: %v", err)
	} else {
		ts.t.Logf("I: set manifest, num=%d", tf.Num())
	}
	return err
}

func (ts *testStorage) Close() error {
	ts.CloseCheck()
	err := ts.Storage.Close()
	if err != nil {
		ts.t.Errorf("E: closing storage failed: %v", err)
	} else {
		ts.t.Log("I: storage closed")
	}
	if ts.closeFn != nil {
		if err := ts.closeFn(); err != nil {
			ts.t.Errorf("E: close function: %v", err)
		}
	}
	return err
}

func (ts *testStorage) CloseCheck() {
	ts.mu.Lock()
	if len(ts.opens) == 0 {
		ts.t.Log("I: all files are closed")
	} else {
		ts.t.Errorf("E: %d files still open", len(ts.opens))
		for x, writer := range ts.opens {
			num, tt := x>>typeShift, storage.FileType(x)&storage.TypeAll
			ts.t.Errorf("E: * num=%d type=%v writer=%v", num, tt, writer)
		}
	}
	ts.mu.Unlock()
}

func newTestStorage(t *testing.T) *testStorage {
	var stor storage.Storage
	var closeFn func() error
	if tsFS {
		for {
			tsMU.Lock()
			num := tsNum
			tsNum++
			tsMU.Unlock()
			tempdir := tsTempdir
			if tempdir == "" {
				tempdir = os.TempDir()
			}
			path := filepath.Join(tempdir, fmt.Sprintf("goleveldb-test%d0%d0%d", os.Getuid(), os.Getpid(), num))
			if _, err := os.Stat(path); err != nil {
				stor, err = storage.OpenFile(path)
				if err != nil {
					t.Fatalf("F: cannot create storage: %v", err)
				}
				t.Logf("I: storage created: %s", path)
				closeFn = func() error {
					for _, name := range []string{"LOG.old", "LOG"} {
						f, err := os.Open(filepath.Join(path, name))
						if err != nil {
							continue
						}
						if log, err := ioutil.ReadAll(f); err != nil {
							t.Logf("---------------------- %s ----------------------", name)
							t.Logf("cannot read log: %v", err)
							t.Logf("---------------------- %s ----------------------", name)
						} else if len(log) > 0 {
							t.Logf("---------------------- %s ----------------------\n%s", name, string(log))
							t.Logf("---------------------- %s ----------------------", name)
						}
						f.Close()
					}
					if t.Failed() {
						t.Logf("testing failed, test DB preserved at %s", path)
						return nil
					}
					if tsKeepFS {
						return nil
					}
					return os.RemoveAll(path)
				}

				break
			}
		}
	} else {
		stor = storage.NewMemStorage()
	}
	ts := &testStorage{
		t:              t,
		Storage:        stor,
		closeFn:        closeFn,
		opens:          make(map[uint64]bool),
		emuErrOnceMap:  make(map[uint64]uint),
		emuRandErrProb: 0x999,
		emuRandRand:    rand.New(rand.NewSource(0xfacedead)),
	}
	ts.cond.L = &ts.mu
	return ts
}
