package raftNode

import (
	"PPOSUtils/utils"
	"time"
)

func NewRaftBatch(raftHost *RaftHost) *raftBatch {
	return &raftBatch{
		raftHost: raftHost,
		data:     []byte{},
	}
}

// raftBatch is a write batch.
type raftBatch struct {
	raftHost *RaftHost
	data     []byte
}

func (that *raftBatch) Set(key string, value interface{}, expire ...int64) BatchInterface {
	that.MSet(DATATYPE_BASE, key, value, expire...)
	return that
}

func (that *raftBatch) MSet(tree, key string, value interface{}, expire ...int64) BatchInterface {
	_value := ""
	switch _t := value.(type) {
	case int, int8, int16, int32, int64, uint8, uint16, uint32, uint64:
		_value = utils.ToString(_t)
	case string:
		_value = _t
	case []byte:
		_value = string(_t)
	}
	_expire := int64(0)
	if len(expire) > 0 {
		_expire = expire[0]
	}
	_data := FsmKvData{
		FsmData: FsmData{
			Tr:  tree,
			Ty:  DATATYPE_BASE,
			Ke:  key,
			Val: _value,
		},
		PreDomain: utils.ToString(_expire, true),
	}
	that.Put(_data)
	return that
}

func (that *raftBatch) Del(key string) BatchInterface {
	that.MDel(DATATYPE_BASE, key)
	return that
}

func (that *raftBatch) MDel(tree, key string) BatchInterface {
	that.remove(newEntryKey(tree, key).CenerateEntryKey())
	return that
}

func (that *raftBatch) Commit(timeout ...time.Duration) error {
	_timeout := time.Duration(5) * time.Second
	if len(timeout) > 0 {
		_timeout = timeout[0]
	}
	_rs := that.raftHost.Apply(that.data, _timeout)
	return _rs
}

func (that *raftBatch) Close() {
	that.raftHost = nil
	that.data = nil
}

func (that *raftBatch) Put(data FsmDataInterface) *raftBatch {
	_data := encodeData("put", newEntry(data).CenerateEntry())
	that.data = append(that.data, _data...)
	return that
}

func (that *raftBatch) remove(key string) {
	_data := encodeData("del", []byte(key))
	that.data = append(that.data, _data...)
}

//func (that *raftBatch) applyType(applyType string, data []byte) []byte {
//	_data := make([]byte, 8)
//	copy(_data, []byte(applyType))
//	_num := make([]byte, 8)
//	binary.LittleEndian.PutUint64(_num, uint64(len(data)))
//	_data = append(_data, _num...)
//	_data = append(_data, data...)
//	return _data
//}
