// Copyright (c) 2014, 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 LICENSE file.

package testutil

import (
	"bytes"
	"fmt"
	"io"
	"math/rand"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"sync"

	. "github.com/onsi/gomega"

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

var (
	storageMu     sync.Mutex
	storageUseFS  bool = true
	storageKeepFS bool = false
	storageNum    int
)

type StorageMode int

const (
	ModeOpen StorageMode = 1 << iota
	ModeCreate
	ModeRemove
	ModeRename
	ModeRead
	ModeWrite
	ModeSync
	ModeClose
)

const (
	modeOpen = iota
	modeCreate
	modeRemove
	modeRename
	modeRead
	modeWrite
	modeSync
	modeClose

	modeCount
)

const (
	typeManifest = iota
	typeJournal
	typeTable
	typeTemp

	typeCount
)

const flattenCount = modeCount * typeCount

func flattenType(m StorageMode, t storage.FileType) int {
	var x int
	switch m {
	case ModeOpen:
		x = modeOpen
	case ModeCreate:
		x = modeCreate
	case ModeRemove:
		x = modeRemove
	case ModeRename:
		x = modeRename
	case ModeRead:
		x = modeRead
	case ModeWrite:
		x = modeWrite
	case ModeSync:
		x = modeSync
	case ModeClose:
		x = modeClose
	default:
		panic("invalid storage mode")
	}
	x *= typeCount
	switch t {
	case storage.TypeManifest:
		return x + typeManifest
	case storage.TypeJournal:
		return x + typeJournal
	case storage.TypeTable:
		return x + typeTable
	case storage.TypeTemp:
		return x + typeTemp
	default:
		panic("invalid file type")
	}
}

func listFlattenType(m StorageMode, t storage.FileType) []int {
	ret := make([]int, 0, flattenCount)
	add := func(x int) {
		x *= typeCount
		switch {
		case t&storage.TypeManifest != 0:
			ret = append(ret, x+typeManifest)
		case t&storage.TypeJournal != 0:
			ret = append(ret, x+typeJournal)
		case t&storage.TypeTable != 0:
			ret = append(ret, x+typeTable)
		case t&storage.TypeTemp != 0:
			ret = append(ret, x+typeTemp)
		}
	}
	switch {
	case m&ModeOpen != 0:
		add(modeOpen)
	case m&ModeCreate != 0:
		add(modeCreate)
	case m&ModeRemove != 0:
		add(modeRemove)
	case m&ModeRename != 0:
		add(modeRename)
	case m&ModeRead != 0:
		add(modeRead)
	case m&ModeWrite != 0:
		add(modeWrite)
	case m&ModeSync != 0:
		add(modeSync)
	case m&ModeClose != 0:
		add(modeClose)
	}
	return ret
}

func packFile(fd storage.FileDesc) uint64 {
	if fd.Num>>(63-typeCount) != 0 {
		panic("overflow")
	}
	return uint64(fd.Num<<typeCount) | uint64(fd.Type)
}

func unpackFile(x uint64) storage.FileDesc {
	return storage.FileDesc{storage.FileType(x) & storage.TypeAll, int64(x >> typeCount)}
}

type emulatedError struct {
	err error
}

func (err emulatedError) Error() string {
	return fmt.Sprintf("emulated storage error: %v", err.err)
}

type storageLock struct {
	s *Storage
	r util.Releaser
}

func (l storageLock) Release() {
	l.r.Release()
	l.s.logI("storage lock released")
}

type reader struct {
	s  *Storage
	fd storage.FileDesc
	storage.Reader
}

func (r *reader) Read(p []byte) (n int, err error) {
	err = r.s.emulateError(ModeRead, r.fd.Type)
	if err == nil {
		r.s.stall(ModeRead, r.fd.Type)
		n, err = r.Reader.Read(p)
	}
	r.s.count(ModeRead, r.fd.Type, n)
	if err != nil && err != io.EOF {
		r.s.logI("read error, fd=%s n=%d err=%v", r.fd, n, err)
	}
	return
}

func (r *reader) ReadAt(p []byte, off int64) (n int, err error) {
	err = r.s.emulateError(ModeRead, r.fd.Type)
	if err == nil {
		r.s.stall(ModeRead, r.fd.Type)
		n, err = r.Reader.ReadAt(p, off)
	}
	r.s.count(ModeRead, r.fd.Type, n)
	if err != nil && err != io.EOF {
		r.s.logI("readAt error, fd=%s offset=%d n=%d err=%v", r.fd, off, n, err)
	}
	return
}

func (r *reader) Close() (err error) {
	return r.s.fileClose(r.fd, r.Reader)
}

type writer struct {
	s  *Storage
	fd storage.FileDesc
	storage.Writer
}

func (w *writer) Write(p []byte) (n int, err error) {
	err = w.s.emulateError(ModeWrite, w.fd.Type)
	if err == nil {
		w.s.stall(ModeWrite, w.fd.Type)
		n, err = w.Writer.Write(p)
	}
	w.s.count(ModeWrite, w.fd.Type, n)
	if err != nil && err != io.EOF {
		w.s.logI("write error, fd=%s n=%d err=%v", w.fd, n, err)
	}
	return
}

func (w *writer) Sync() (err error) {
	err = w.s.emulateError(ModeSync, w.fd.Type)
	if err == nil {
		w.s.stall(ModeSync, w.fd.Type)
		err = w.Writer.Sync()
	}
	w.s.count(ModeSync, w.fd.Type, 0)
	if err != nil {
		w.s.logI("sync error, fd=%s err=%v", w.fd, err)
	}
	return
}

func (w *writer) Close() (err error) {
	return w.s.fileClose(w.fd, w.Writer)
}

type Storage struct {
	storage.Storage
	path    string
	onClose func() (preserve bool, err error)
	onLog   func(str string)

	lmu sync.Mutex
	lb  bytes.Buffer

	mu   sync.Mutex
	rand *rand.Rand
	// Open files, true=writer, false=reader
	opens                   map[uint64]bool
	counters                [flattenCount]int
	bytesCounter            [flattenCount]int64
	emulatedError           [flattenCount]error
	emulatedErrorOnce       [flattenCount]bool
	emulatedRandomError     [flattenCount]error
	emulatedRandomErrorProb [flattenCount]float64
	stallCond               sync.Cond
	stalled                 [flattenCount]bool
}

func (s *Storage) log(skip int, str string) {
	s.lmu.Lock()
	defer s.lmu.Unlock()
	_, file, line, ok := runtime.Caller(skip + 2)
	if ok {
		// Truncate file name at last file name separator.
		if index := strings.LastIndex(file, "/"); index >= 0 {
			file = file[index+1:]
		} else if index = strings.LastIndex(file, "\\"); index >= 0 {
			file = file[index+1:]
		}
	} else {
		file = "???"
		line = 1
	}
	fmt.Fprintf(&s.lb, "%s:%d: ", file, line)
	lines := strings.Split(str, "\n")
	if l := len(lines); l > 1 && lines[l-1] == "" {
		lines = lines[:l-1]
	}
	for i, line := range lines {
		if i > 0 {
			s.lb.WriteString("\n\t")
		}
		s.lb.WriteString(line)
	}
	if s.onLog != nil {
		s.onLog(s.lb.String())
		s.lb.Reset()
	} else {
		s.lb.WriteByte('\n')
	}
}

func (s *Storage) logISkip(skip int, format string, args ...interface{}) {
	pc, _, _, ok := runtime.Caller(skip + 1)
	if ok {
		if f := runtime.FuncForPC(pc); f != nil {
			fname := f.Name()
			if index := strings.LastIndex(fname, "."); index >= 0 {
				fname = fname[index+1:]
			}
			format = fname + ": " + format
		}
	}
	s.log(skip+1, fmt.Sprintf(format, args...))
}

func (s *Storage) logI(format string, args ...interface{}) {
	s.logISkip(1, format, args...)
}

func (s *Storage) OnLog(onLog func(log string)) {
	s.lmu.Lock()
	s.onLog = onLog
	if s.lb.Len() != 0 {
		log := s.lb.String()
		s.onLog(log[:len(log)-1])
		s.lb.Reset()
	}
	s.lmu.Unlock()
}

func (s *Storage) Log(str string) {
	s.log(1, "Log: "+str)
	s.Storage.Log(str)
}

func (s *Storage) Lock() (l storage.Lock, err error) {
	l, err = s.Storage.Lock()
	if err != nil {
		s.logI("storage locking failed, err=%v", err)
	} else {
		s.logI("storage locked")
		l = storageLock{s, l}
	}
	return
}

func (s *Storage) List(t storage.FileType) (fds []storage.FileDesc, err error) {
	fds, err = s.Storage.List(t)
	if err != nil {
		s.logI("list failed, err=%v", err)
		return
	}
	s.logI("list, type=0x%x count=%d", int(t), len(fds))
	return
}

func (s *Storage) GetMeta() (fd storage.FileDesc, err error) {
	fd, err = s.Storage.GetMeta()
	if err != nil {
		if !os.IsNotExist(err) {
			s.logI("get meta failed, err=%v", err)
		}
		return
	}
	s.logI("get meta, fd=%s", fd)
	return
}

func (s *Storage) SetMeta(fd storage.FileDesc) error {
	ExpectWithOffset(1, fd.Type).To(Equal(storage.TypeManifest))
	err := s.Storage.SetMeta(fd)
	if err != nil {
		s.logI("set meta failed, fd=%s err=%v", fd, err)
	} else {
		s.logI("set meta, fd=%s", fd)
	}
	return err
}

func (s *Storage) fileClose(fd storage.FileDesc, closer io.Closer) (err error) {
	err = s.emulateError(ModeClose, fd.Type)
	if err == nil {
		s.stall(ModeClose, fd.Type)
	}
	x := packFile(fd)
	s.mu.Lock()
	defer s.mu.Unlock()
	if err == nil {
		ExpectWithOffset(2, s.opens).To(HaveKey(x), "File closed, fd=%s", fd)
		err = closer.Close()
	}
	s.countNB(ModeClose, fd.Type, 0)
	writer := s.opens[x]
	if err != nil {
		s.logISkip(1, "file close failed, fd=%s writer=%v err=%v", fd, writer, err)
	} else {
		s.logISkip(1, "file closed, fd=%s writer=%v", fd, writer)
		delete(s.opens, x)
	}
	return
}

func (s *Storage) assertOpen(fd storage.FileDesc) {
	x := packFile(fd)
	ExpectWithOffset(2, s.opens).NotTo(HaveKey(x), "File open, fd=%s writer=%v", fd, s.opens[x])
}

func (s *Storage) Open(fd storage.FileDesc) (r storage.Reader, err error) {
	err = s.emulateError(ModeOpen, fd.Type)
	if err == nil {
		s.stall(ModeOpen, fd.Type)
	}
	s.mu.Lock()
	defer s.mu.Unlock()
	if err == nil {
		s.assertOpen(fd)
		s.countNB(ModeOpen, fd.Type, 0)
		r, err = s.Storage.Open(fd)
	}
	if err != nil {
		s.logI("file open failed, fd=%s err=%v", fd, err)
	} else {
		s.logI("file opened, fd=%s", fd)
		s.opens[packFile(fd)] = false
		r = &reader{s, fd, r}
	}
	return
}

func (s *Storage) Create(fd storage.FileDesc) (w storage.Writer, err error) {
	err = s.emulateError(ModeCreate, fd.Type)
	if err == nil {
		s.stall(ModeCreate, fd.Type)
	}
	s.mu.Lock()
	defer s.mu.Unlock()
	if err == nil {
		s.assertOpen(fd)
		s.countNB(ModeCreate, fd.Type, 0)
		w, err = s.Storage.Create(fd)
	}
	if err != nil {
		s.logI("file create failed, fd=%s err=%v", fd, err)
	} else {
		s.logI("file created, fd=%s", fd)
		s.opens[packFile(fd)] = true
		w = &writer{s, fd, w}
	}
	return
}

func (s *Storage) Remove(fd storage.FileDesc) (err error) {
	err = s.emulateError(ModeRemove, fd.Type)
	if err == nil {
		s.stall(ModeRemove, fd.Type)
	}
	s.mu.Lock()
	defer s.mu.Unlock()
	if err == nil {
		s.assertOpen(fd)
		s.countNB(ModeRemove, fd.Type, 0)
		err = s.Storage.Remove(fd)
	}
	if err != nil {
		s.logI("file remove failed, fd=%s err=%v", fd, err)
	} else {
		s.logI("file removed, fd=%s", fd)
	}
	return
}

func (s *Storage) ForceRemove(fd storage.FileDesc) (err error) {
	s.countNB(ModeRemove, fd.Type, 0)
	if err = s.Storage.Remove(fd); err != nil {
		s.logI("file remove failed (forced), fd=%s err=%v", fd, err)
	} else {
		s.logI("file removed (forced), fd=%s", fd)
	}
	return
}

func (s *Storage) Rename(oldfd, newfd storage.FileDesc) (err error) {
	err = s.emulateError(ModeRename, oldfd.Type)
	if err == nil {
		s.stall(ModeRename, oldfd.Type)
	}
	s.mu.Lock()
	defer s.mu.Unlock()
	if err == nil {
		s.assertOpen(oldfd)
		s.assertOpen(newfd)
		s.countNB(ModeRename, oldfd.Type, 0)
		err = s.Storage.Rename(oldfd, newfd)
	}
	if err != nil {
		s.logI("file rename failed, oldfd=%s newfd=%s err=%v", oldfd, newfd, err)
	} else {
		s.logI("file renamed, oldfd=%s newfd=%s", oldfd, newfd)
	}
	return
}

func (s *Storage) ForceRename(oldfd, newfd storage.FileDesc) (err error) {
	s.countNB(ModeRename, oldfd.Type, 0)
	if err = s.Storage.Rename(oldfd, newfd); err != nil {
		s.logI("file rename failed (forced), oldfd=%s newfd=%s err=%v", oldfd, newfd, err)
	} else {
		s.logI("file renamed (forced), oldfd=%s newfd=%s", oldfd, newfd)
	}
	return
}

func (s *Storage) openFiles() string {
	out := "Open files:"
	for x, writer := range s.opens {
		fd := unpackFile(x)
		out += fmt.Sprintf("\n · fd=%s writer=%v", fd, writer)
	}
	return out
}

func (s *Storage) CloseCheck() {
	s.mu.Lock()
	defer s.mu.Unlock()
	ExpectWithOffset(1, s.opens).To(BeEmpty(), s.openFiles())
}

func (s *Storage) OnClose(onClose func() (preserve bool, err error)) {
	s.mu.Lock()
	s.onClose = onClose
	s.mu.Unlock()
}

func (s *Storage) Close() error {
	s.mu.Lock()
	defer s.mu.Unlock()
	ExpectWithOffset(1, s.opens).To(BeEmpty(), s.openFiles())
	err := s.Storage.Close()
	if err != nil {
		s.logI("storage closing failed, err=%v", err)
	} else {
		s.logI("storage closed")
	}
	var preserve bool
	if s.onClose != nil {
		var err0 error
		if preserve, err0 = s.onClose(); err0 != nil {
			s.logI("onClose error, err=%v", err0)
		}
	}
	if s.path != "" {
		if storageKeepFS || preserve {
			s.logI("storage is preserved, path=%v", s.path)
		} else {
			if err1 := os.RemoveAll(s.path); err1 != nil {
				s.logI("cannot remove storage, err=%v", err1)
			} else {
				s.logI("storage has been removed")
			}
		}
	}
	return err
}

func (s *Storage) countNB(m StorageMode, t storage.FileType, n int) {
	s.counters[flattenType(m, t)]++
	s.bytesCounter[flattenType(m, t)] += int64(n)
}

func (s *Storage) count(m StorageMode, t storage.FileType, n int) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.countNB(m, t, n)
}

func (s *Storage) ResetCounter(m StorageMode, t storage.FileType) {
	for _, x := range listFlattenType(m, t) {
		s.counters[x] = 0
		s.bytesCounter[x] = 0
	}
}

func (s *Storage) Counter(m StorageMode, t storage.FileType) (count int, bytes int64) {
	for _, x := range listFlattenType(m, t) {
		count += s.counters[x]
		bytes += s.bytesCounter[x]
	}
	return
}

func (s *Storage) emulateError(m StorageMode, t storage.FileType) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	x := flattenType(m, t)
	if err := s.emulatedError[x]; err != nil {
		if s.emulatedErrorOnce[x] {
			s.emulatedError[x] = nil
		}
		return emulatedError{err}
	}
	if err := s.emulatedRandomError[x]; err != nil && s.rand.Float64() < s.emulatedRandomErrorProb[x] {
		return emulatedError{err}
	}
	return nil
}

func (s *Storage) EmulateError(m StorageMode, t storage.FileType, err error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, x := range listFlattenType(m, t) {
		s.emulatedError[x] = err
		s.emulatedErrorOnce[x] = false
	}
}

func (s *Storage) EmulateErrorOnce(m StorageMode, t storage.FileType, err error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, x := range listFlattenType(m, t) {
		s.emulatedError[x] = err
		s.emulatedErrorOnce[x] = true
	}
}

func (s *Storage) EmulateRandomError(m StorageMode, t storage.FileType, prob float64, err error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, x := range listFlattenType(m, t) {
		s.emulatedRandomError[x] = err
		s.emulatedRandomErrorProb[x] = prob
	}
}

func (s *Storage) stall(m StorageMode, t storage.FileType) {
	x := flattenType(m, t)
	s.mu.Lock()
	defer s.mu.Unlock()
	for s.stalled[x] {
		s.stallCond.Wait()
	}
}

func (s *Storage) Stall(m StorageMode, t storage.FileType) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, x := range listFlattenType(m, t) {
		s.stalled[x] = true
	}
}

func (s *Storage) Release(m StorageMode, t storage.FileType) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, x := range listFlattenType(m, t) {
		s.stalled[x] = false
	}
	s.stallCond.Broadcast()
}

func NewStorage() *Storage {
	var (
		stor storage.Storage
		path string
	)
	if storageUseFS {
		for {
			storageMu.Lock()
			num := storageNum
			storageNum++
			storageMu.Unlock()
			path = filepath.Join(os.TempDir(), fmt.Sprintf("goleveldb-test%d0%d0%d", os.Getuid(), os.Getpid(), num))
			if _, err := os.Stat(path); os.IsNotExist(err) {
				stor, err = storage.OpenFile(path)
				ExpectWithOffset(1, err).NotTo(HaveOccurred(), "creating storage at %s", path)
				break
			}
		}
	} else {
		stor = storage.NewMemStorage()
	}
	s := &Storage{
		Storage: stor,
		path:    path,
		rand:    NewRand(),
		opens:   make(map[uint64]bool),
	}
	s.stallCond.L = &s.mu
	if s.path != "" {
		s.logI("using FS storage")
		s.logI("storage path: %s", s.path)
	} else {
		s.logI("using MEM storage")
	}
	return s
}
