// 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 LICENSE file.

// Package opt provides sets of options used by LevelDB.
package opt

import (
	"github.com/syndtr/goleveldb/leveldb/cache"
	"github.com/syndtr/goleveldb/leveldb/comparer"
	"github.com/syndtr/goleveldb/leveldb/filter"
	"math"
)

const (
	KiB = 1024
	MiB = KiB * 1024
	GiB = MiB * 1024
)

var (
	DefaultBlockCacher                   = LRUCacher
	DefaultBlockCacheCapacity            = 8 * MiB
	DefaultBlockRestartInterval          = 16
	DefaultBlockSize                     = 4 * KiB
	DefaultCompactionExpandLimitFactor   = 25
	DefaultCompactionGPOverlapsFactor    = 10
	DefaultCompactionL0Trigger           = 4
	DefaultCompactionSourceLimitFactor   = 1
	DefaultCompactionTableSize           = 2 * MiB
	DefaultCompactionTableSizeMultiplier = 1.0
	DefaultCompactionTotalSize           = 10 * MiB
	DefaultCompactionTotalSizeMultiplier = 10.0
	DefaultCompressionType               = SnappyCompression
	DefaultIteratorSamplingRate          = 1 * MiB
	DefaultMaxMemCompationLevel          = 2
	DefaultNumLevel                      = 7
	DefaultOpenFilesCacher               = LRUCacher
	DefaultOpenFilesCacheCapacity        = 500
	DefaultWriteBuffer                   = 4 * MiB
	DefaultWriteL0PauseTrigger           = 12
	DefaultWriteL0SlowdownTrigger        = 8
)

// Cacher is a caching algorithm.
type Cacher interface {
	New(capacity int) cache.Cacher
}

type CacherFunc struct {
	NewFunc func(capacity int) cache.Cacher
}

func (f *CacherFunc) New(capacity int) cache.Cacher {
	if f.NewFunc != nil {
		return f.NewFunc(capacity)
	}
	return nil
}

func noCacher(int) cache.Cacher { return nil }

var (
	// LRUCacher is the LRU-cache algorithm.
	LRUCacher = &CacherFunc{cache.NewLRU}

	// NoCacher is the value to disable caching algorithm.
	NoCacher = &CacherFunc{}
)

// Compression is the 'sorted table' block compression algorithm to use.
type Compression uint

func (c Compression) String() string {
	switch c {
	case DefaultCompression:
		return "default"
	case NoCompression:
		return "none"
	case SnappyCompression:
		return "snappy"
	}
	return "invalid"
}

const (
	DefaultCompression Compression = iota
	NoCompression
	SnappyCompression
	nCompression
)

// Strict is the DB 'strict level'.
type Strict uint

const (
	// If present then a corrupted or invalid chunk or block in manifest
	// journal will cause an error instead of being dropped.
	// This will prevent database with corrupted manifest to be opened.
	StrictManifest Strict = 1 << iota

	// If present then journal chunk checksum will be verified.
	StrictJournalChecksum

	// If present then a corrupted or invalid chunk or block in journal
	// will cause an error instead of being dropped.
	// This will prevent database with corrupted journal to be opened.
	StrictJournal

	// If present then 'sorted table' block checksum will be verified.
	// This has effect on both 'read operation' and compaction.
	StrictBlockChecksum

	// If present then a corrupted 'sorted table' will fails compaction.
	// The database will enter read-only mode.
	StrictCompaction

	// If present then a corrupted 'sorted table' will halts 'read operation'.
	StrictReader

	// If present then leveldb.Recover will drop corrupted 'sorted table'.
	StrictRecovery

	// This only applicable for ReadOptions, if present then this ReadOptions
	// 'strict level' will override global ones.
	StrictOverride

	// StrictAll enables all strict flags.
	StrictAll = StrictManifest | StrictJournalChecksum | StrictJournal | StrictBlockChecksum | StrictCompaction | StrictReader | StrictRecovery

	// DefaultStrict is the default strict flags. Specify any strict flags
	// will override default strict flags as whole (i.e. not OR'ed).
	DefaultStrict = StrictJournalChecksum | StrictBlockChecksum | StrictCompaction | StrictReader

	// NoStrict disables all strict flags. Override default strict flags.
	NoStrict = ^StrictAll
)

// Options holds the optional parameters for the DB at large.
type Options struct {
	// AltFilters defines one or more 'alternative filters'.
	// 'alternative filters' will be used during reads if a filter block
	// does not match with the 'effective filter'.
	//
	// The default value is nil
	AltFilters []filter.Filter

	// BlockCacher provides cache algorithm for LevelDB 'sorted table' block caching.
	// Specify NoCacher to disable caching algorithm.
	//
	// The default value is LRUCacher.
	BlockCacher Cacher

	// BlockCacheCapacity defines the capacity of the 'sorted table' block caching.
	// Use -1 for zero, this has same effect as specifying NoCacher to BlockCacher.
	//
	// The default value is 8MiB.
	BlockCacheCapacity int

	// BlockRestartInterval is the number of keys between restart points for
	// delta encoding of keys.
	//
	// The default value is 16.
	BlockRestartInterval int

	// BlockSize is the minimum uncompressed size in bytes of each 'sorted table'
	// block.
	//
	// The default value is 4KiB.
	BlockSize int

	// CompactionExpandLimitFactor limits compaction size after expanded.
	// This will be multiplied by table size limit at compaction target level.
	//
	// The default value is 25.
	CompactionExpandLimitFactor int

	// CompactionGPOverlapsFactor limits overlaps in grandparent (Level + 2) that a
	// single 'sorted table' generates.
	// This will be multiplied by table size limit at grandparent level.
	//
	// The default value is 10.
	CompactionGPOverlapsFactor int

	// CompactionL0Trigger defines number of 'sorted table' at level-0 that will
	// trigger compaction.
	//
	// The default value is 4.
	CompactionL0Trigger int

	// CompactionSourceLimitFactor limits compaction source size. This doesn't apply to
	// level-0.
	// This will be multiplied by table size limit at compaction target level.
	//
	// The default value is 1.
	CompactionSourceLimitFactor int

	// CompactionTableSize limits size of 'sorted table' that compaction generates.
	// The limits for each level will be calculated as:
	//   CompactionTableSize * (CompactionTableSizeMultiplier ^ Level)
	// The multiplier for each level can also fine-tuned using CompactionTableSizeMultiplierPerLevel.
	//
	// The default value is 2MiB.
	CompactionTableSize int

	// CompactionTableSizeMultiplier defines multiplier for CompactionTableSize.
	//
	// The default value is 1.
	CompactionTableSizeMultiplier float64

	// CompactionTableSizeMultiplierPerLevel defines per-level multiplier for
	// CompactionTableSize.
	// Use zero to skip a level.
	//
	// The default value is nil.
	CompactionTableSizeMultiplierPerLevel []float64

	// CompactionTotalSize limits total size of 'sorted table' for each level.
	// The limits for each level will be calculated as:
	//   CompactionTotalSize * (CompactionTotalSizeMultiplier ^ Level)
	// The multiplier for each level can also fine-tuned using
	// CompactionTotalSizeMultiplierPerLevel.
	//
	// The default value is 10MiB.
	CompactionTotalSize int

	// CompactionTotalSizeMultiplier defines multiplier for CompactionTotalSize.
	//
	// The default value is 10.
	CompactionTotalSizeMultiplier float64

	// CompactionTotalSizeMultiplierPerLevel defines per-level multiplier for
	// CompactionTotalSize.
	// Use zero to skip a level.
	//
	// The default value is nil.
	CompactionTotalSizeMultiplierPerLevel []float64

	// Comparer defines a total ordering over the space of []byte keys: a 'less
	// than' relationship. The same comparison algorithm must be used for reads
	// and writes over the lifetime of the DB.
	//
	// The default value uses the same ordering as bytes.Compare.
	Comparer comparer.Comparer

	// Compression defines the 'sorted table' block compression to use.
	//
	// The default value (DefaultCompression) uses snappy compression.
	Compression Compression

	// DisableBufferPool allows disable use of util.BufferPool functionality.
	//
	// The default value is false.
	DisableBufferPool bool

	// DisableBlockCache allows disable use of cache.Cache functionality on
	// 'sorted table' block.
	//
	// The default value is false.
	DisableBlockCache bool

	// DisableCompactionBackoff allows disable compaction retry backoff.
	//
	// The default value is false.
	DisableCompactionBackoff bool

	// ErrorIfExist defines whether an error should returned if the DB already
	// exist.
	//
	// The default value is false.
	ErrorIfExist bool

	// ErrorIfMissing defines whether an error should returned if the DB is
	// missing. If false then the database will be created if missing, otherwise
	// an error will be returned.
	//
	// The default value is false.
	ErrorIfMissing bool

	// Filter defines an 'effective filter' to use. An 'effective filter'
	// if defined will be used to generate per-table filter block.
	// The filter name will be stored on disk.
	// During reads LevelDB will try to find matching filter from
	// 'effective filter' and 'alternative filters'.
	//
	// Filter can be changed after a DB has been created. It is recommended
	// to put old filter to the 'alternative filters' to mitigate lack of
	// filter during transition period.
	//
	// A filter is used to reduce disk reads when looking for a specific key.
	//
	// The default value is nil.
	Filter filter.Filter

	// IteratorSamplingRate defines approximate gap (in bytes) between read
	// sampling of an iterator. The samples will be used to determine when
	// compaction should be triggered.
	//
	// The default is 1MiB.
	IteratorSamplingRate int

	// MaxMemCompationLevel defines maximum level a newly compacted 'memdb'
	// will be pushed into if doesn't creates overlap. This should less than
	// NumLevel. Use -1 for level-0.
	//
	// The default is 2.
	MaxMemCompationLevel int

	// NumLevel defines number of database level. The level shouldn't changed
	// between opens, or the database will panic.
	//
	// The default is 7.
	NumLevel int

	// OpenFilesCacher provides cache algorithm for open files caching.
	// Specify NoCacher to disable caching algorithm.
	//
	// The default value is LRUCacher.
	OpenFilesCacher Cacher

	// OpenFilesCacheCapacity defines the capacity of the open files caching.
	// Use -1 for zero, this has same effect as specifying NoCacher to OpenFilesCacher.
	//
	// The default value is 500.
	OpenFilesCacheCapacity int

	// Strict defines the DB strict level.
	Strict Strict

	// WriteBuffer defines maximum size of a 'memdb' before flushed to
	// 'sorted table'. 'memdb' is an in-memory DB backed by an on-disk
	// unsorted journal.
	//
	// LevelDB may held up to two 'memdb' at the same time.
	//
	// The default value is 4MiB.
	WriteBuffer int

	// WriteL0StopTrigger defines number of 'sorted table' at level-0 that will
	// pause write.
	//
	// The default value is 12.
	WriteL0PauseTrigger int

	// WriteL0SlowdownTrigger defines number of 'sorted table' at level-0 that
	// will trigger write slowdown.
	//
	// The default value is 8.
	WriteL0SlowdownTrigger int
}

func (o *Options) GetAltFilters() []filter.Filter {
	if o == nil {
		return nil
	}
	return o.AltFilters
}

func (o *Options) GetBlockCacher() Cacher {
	if o == nil || o.BlockCacher == nil {
		return DefaultBlockCacher
	} else if o.BlockCacher == NoCacher {
		return nil
	}
	return o.BlockCacher
}

func (o *Options) GetBlockCacheCapacity() int {
	if o == nil || o.BlockCacheCapacity == 0 {
		return DefaultBlockCacheCapacity
	} else if o.BlockCacheCapacity < 0 {
		return 0
	}
	return o.BlockCacheCapacity
}

func (o *Options) GetBlockRestartInterval() int {
	if o == nil || o.BlockRestartInterval <= 0 {
		return DefaultBlockRestartInterval
	}
	return o.BlockRestartInterval
}

func (o *Options) GetBlockSize() int {
	if o == nil || o.BlockSize <= 0 {
		return DefaultBlockSize
	}
	return o.BlockSize
}

func (o *Options) GetCompactionExpandLimit(level int) int {
	factor := DefaultCompactionExpandLimitFactor
	if o != nil && o.CompactionExpandLimitFactor > 0 {
		factor = o.CompactionExpandLimitFactor
	}
	return o.GetCompactionTableSize(level+1) * factor
}

func (o *Options) GetCompactionGPOverlaps(level int) int {
	factor := DefaultCompactionGPOverlapsFactor
	if o != nil && o.CompactionGPOverlapsFactor > 0 {
		factor = o.CompactionGPOverlapsFactor
	}
	return o.GetCompactionTableSize(level+2) * factor
}

func (o *Options) GetCompactionL0Trigger() int {
	if o == nil || o.CompactionL0Trigger == 0 {
		return DefaultCompactionL0Trigger
	}
	return o.CompactionL0Trigger
}

func (o *Options) GetCompactionSourceLimit(level int) int {
	factor := DefaultCompactionSourceLimitFactor
	if o != nil && o.CompactionSourceLimitFactor > 0 {
		factor = o.CompactionSourceLimitFactor
	}
	return o.GetCompactionTableSize(level+1) * factor
}

func (o *Options) GetCompactionTableSize(level int) int {
	var (
		base = DefaultCompactionTableSize
		mult float64
	)
	if o != nil {
		if o.CompactionTableSize > 0 {
			base = o.CompactionTableSize
		}
		if len(o.CompactionTableSizeMultiplierPerLevel) > level && o.CompactionTableSizeMultiplierPerLevel[level] > 0 {
			mult = o.CompactionTableSizeMultiplierPerLevel[level]
		} else if o.CompactionTableSizeMultiplier > 0 {
			mult = math.Pow(o.CompactionTableSizeMultiplier, float64(level))
		}
	}
	if mult == 0 {
		mult = math.Pow(DefaultCompactionTableSizeMultiplier, float64(level))
	}
	return int(float64(base) * mult)
}

func (o *Options) GetCompactionTotalSize(level int) int64 {
	var (
		base = DefaultCompactionTotalSize
		mult float64
	)
	if o != nil {
		if o.CompactionTotalSize > 0 {
			base = o.CompactionTotalSize
		}
		if len(o.CompactionTotalSizeMultiplierPerLevel) > level && o.CompactionTotalSizeMultiplierPerLevel[level] > 0 {
			mult = o.CompactionTotalSizeMultiplierPerLevel[level]
		} else if o.CompactionTotalSizeMultiplier > 0 {
			mult = math.Pow(o.CompactionTotalSizeMultiplier, float64(level))
		}
	}
	if mult == 0 {
		mult = math.Pow(DefaultCompactionTotalSizeMultiplier, float64(level))
	}
	return int64(float64(base) * mult)
}

func (o *Options) GetComparer() comparer.Comparer {
	if o == nil || o.Comparer == nil {
		return comparer.DefaultComparer
	}
	return o.Comparer
}

func (o *Options) GetCompression() Compression {
	if o == nil || o.Compression <= DefaultCompression || o.Compression >= nCompression {
		return DefaultCompressionType
	}
	return o.Compression
}

func (o *Options) GetDisableBufferPool() bool {
	if o == nil {
		return false
	}
	return o.DisableBufferPool
}

func (o *Options) GetDisableBlockCache() bool {
	if o == nil {
		return false
	}
	return o.DisableBlockCache
}

func (o *Options) GetDisableCompactionBackoff() bool {
	if o == nil {
		return false
	}
	return o.DisableCompactionBackoff
}

func (o *Options) GetErrorIfExist() bool {
	if o == nil {
		return false
	}
	return o.ErrorIfExist
}

func (o *Options) GetErrorIfMissing() bool {
	if o == nil {
		return false
	}
	return o.ErrorIfMissing
}

func (o *Options) GetFilter() filter.Filter {
	if o == nil {
		return nil
	}
	return o.Filter
}

func (o *Options) GetIteratorSamplingRate() int {
	if o == nil || o.IteratorSamplingRate <= 0 {
		return DefaultIteratorSamplingRate
	}
	return o.IteratorSamplingRate
}

func (o *Options) GetMaxMemCompationLevel() int {
	level := DefaultMaxMemCompationLevel
	if o != nil {
		if o.MaxMemCompationLevel > 0 {
			level = o.MaxMemCompationLevel
		} else if o.MaxMemCompationLevel < 0 {
			level = 0
		}
	}
	if level >= o.GetNumLevel() {
		return o.GetNumLevel() - 1
	}
	return level
}

func (o *Options) GetNumLevel() int {
	if o == nil || o.NumLevel <= 0 {
		return DefaultNumLevel
	}
	return o.NumLevel
}

func (o *Options) GetOpenFilesCacher() Cacher {
	if o == nil || o.OpenFilesCacher == nil {
		return DefaultOpenFilesCacher
	}
	if o.OpenFilesCacher == NoCacher {
		return nil
	}
	return o.OpenFilesCacher
}

func (o *Options) GetOpenFilesCacheCapacity() int {
	if o == nil || o.OpenFilesCacheCapacity == 0 {
		return DefaultOpenFilesCacheCapacity
	} else if o.OpenFilesCacheCapacity < 0 {
		return 0
	}
	return o.OpenFilesCacheCapacity
}

func (o *Options) GetStrict(strict Strict) bool {
	if o == nil || o.Strict == 0 {
		return DefaultStrict&strict != 0
	}
	return o.Strict&strict != 0
}

func (o *Options) GetWriteBuffer() int {
	if o == nil || o.WriteBuffer <= 0 {
		return DefaultWriteBuffer
	}
	return o.WriteBuffer
}

func (o *Options) GetWriteL0PauseTrigger() int {
	if o == nil || o.WriteL0PauseTrigger == 0 {
		return DefaultWriteL0PauseTrigger
	}
	return o.WriteL0PauseTrigger
}

func (o *Options) GetWriteL0SlowdownTrigger() int {
	if o == nil || o.WriteL0SlowdownTrigger == 0 {
		return DefaultWriteL0SlowdownTrigger
	}
	return o.WriteL0SlowdownTrigger
}

// ReadOptions holds the optional parameters for 'read operation'. The
// 'read operation' includes Get, Find and NewIterator.
type ReadOptions struct {
	// DontFillCache defines whether block reads for this 'read operation'
	// should be cached. If false then the block will be cached. This does
	// not affects already cached block.
	//
	// The default value is false.
	DontFillCache bool

	// Strict will be OR'ed with global DB 'strict level' unless StrictOverride
	// is present. Currently only StrictReader that has effect here.
	Strict Strict
}

func (ro *ReadOptions) GetDontFillCache() bool {
	if ro == nil {
		return false
	}
	return ro.DontFillCache
}

func (ro *ReadOptions) GetStrict(strict Strict) bool {
	if ro == nil {
		return false
	}
	return ro.Strict&strict != 0
}

// WriteOptions holds the optional parameters for 'write operation'. The
// 'write operation' includes Write, Put and Delete.
type WriteOptions struct {
	// Sync is whether to sync underlying writes from the OS buffer cache
	// through to actual disk, if applicable. Setting Sync can result in
	// slower writes.
	//
	// If false, and the machine crashes, then some recent writes may be lost.
	// Note that if it is just the process that crashes (and the machine does
	// not) then no writes will be lost.
	//
	// In other words, Sync being false has the same semantics as a write
	// system call. Sync being true means write followed by fsync.
	//
	// The default value is false.
	Sync bool
}

func (wo *WriteOptions) GetSync() bool {
	if wo == nil {
		return false
	}
	return wo.Sync
}

func GetStrict(o *Options, ro *ReadOptions, strict Strict) bool {
	if ro.GetStrict(StrictOverride) {
		return ro.GetStrict(strict)
	} else {
		return o.GetStrict(strict) || ro.GetStrict(strict)
	}
}
