package raftNode

import (
	"bytes"
	"encoding/binary"
	"time"
)

//uidData id生成器的数据结构
type uidData struct {
	uid       int64  //自增id
	preDomain int64  //前置域
	name      string //关键字
}

func encodeData(name string, data []byte) []byte {
	_data := make([]byte, 8)
	copy(_data, []byte(name))
	_data = append(_data, data...)
	_num := make([]byte, 8)
	binary.LittleEndian.PutUint64(_num, uint64(len(_data)+8))
	_data = append(_num, _data...)
	return _data
}

func decodeData(data []byte) (string, []byte, []byte) {
	_len := binary.LittleEndian.Uint64(data[0:8])
	_last := []byte{}
	if uint64(len(data)) > _len {
		_last = data[_len:]
	}
	_space := make([]byte, 1)
	return string(bytes.Trim(data[8:16], string(_space))), data[16:_len], _last
}

type FsmInterface interface {
	Find(tree, key string) interface{}
	List() []interface{}
}

type BatchInterface interface {
	Set(key string, value interface{}, expire ...int64) BatchInterface
	MSet(tree, key string, value interface{}, expire ...int64) BatchInterface
	MDel(tree, key string) BatchInterface
	Del(key string) BatchInterface
	Commit(timeout ...time.Duration) error
}

type StorageInterface interface {
	IsLeader() bool
	ForceUUID(name string, id, preDomain int64) (int64, error)
	NewUUID(name string, id, preDomain int64, step ...int64) (int64, error)
	SessionLock(domain, sessionID string, maxActive, expire int64) (bool, error)
	SessionUnLock(domain, sessionID string) error
	Set(key string, value interface{}, expire ...int64) error
	MSet(tree, key string, value interface{}, expire ...int64) error
	Get(key string) (interface{}, int64)
	MGet(tree, key string) (interface{}, int64)
	MDel(tree, key string) error
	Del(key string) error
	Batch() BatchInterface
	Task(runTime int, action func())
	RegisterLeaderEventHandler(handler func(isLeader bool) error)
	RegisterUUidLoadHandler(loadHandler func(tree, key string, value interface{}, preDomain string))
	RegisterLockLoadHandler(loadHandler func(tree, key string, value interface{}, preDomain string))
	RegisterLoadHandler(loadHandler func(tree, key string, value interface{}, expire int64))
}

type LogerInterface interface {
	SetLevel(level int)
	GetLevel() int
	Trace(args ...interface{})
	Tracef(template string, args ...interface{})
	Debug(args ...interface{})
	Debugf(template string, args ...interface{})
	Info(args ...interface{})
	Infof(template string, args ...interface{})
	Warn(args ...interface{})
	Warnf(template string, args ...interface{})
	Error(args ...interface{})
	Errorf(template string, args ...interface{})
	Fatal(args ...interface{})
	Fatalf(template string, args ...interface{})
	Panic(args ...interface{})
	Panicf(template string, args ...interface{})
}
