package dbserver

import (
	"sync"
	"time"
)

//实现一个缓存存列表
//可以添加、删除元素、不存在时添加
//添加：列表中不存在时添加，存在时替换
//删除列表：按照添加时的顺序删除元素

type saveItem struct {
	val  interface{}
	tick int64
}

type CacheSaveList struct {
	sync.Mutex
	allItem   map[string]*saveItem
	orderItem []string
	pool      sync.Pool
}

func NewCacheList() *CacheSaveList {
	l := new(CacheSaveList)
	l.orderItem = make([]string, 0)
	l.allItem = make(map[string]*saveItem)
	l.pool.New = func() interface{} {
		return new(saveItem)
	}
	return l
}

func (l *CacheSaveList) newSaveItem(val interface{}) *saveItem {
	it := l.pool.Get()
	it1 := it.(*saveItem)

	it1.val = val
	it1.tick = time.Now().Unix()
	return it1
}

func (l *CacheSaveList) Add(key string, val interface{}) int {
	l.Lock()
	defer l.Unlock()

	if v, ok := l.allItem[key]; !ok {
		l.orderItem = append(l.orderItem, key)
		it1 := l.newSaveItem(val)
		l.allItem[key] = it1
	} else {
		v.val = val
	}

	return len(l.orderItem)
}

//列表中不存在时添加，
func (l *CacheSaveList) Addnx(key string, val interface{}) {
	l.Lock()
	defer l.Unlock()

	if _, ok := l.allItem[key]; !ok {
		l.orderItem = append(l.orderItem, key)
		it1 := l.newSaveItem(val)
		l.allItem[key] = it1
	}
}

func (l *CacheSaveList) Pop() interface{} {
	l.Lock()
	defer l.Unlock()

	if len(l.orderItem) == 0 {
		// if len(l.allItem) > 0 {
		// 	l.allItem = make(map[int64]interface{})
		// }
		return nil
	}

	k := l.orderItem[0]
	l.orderItem = l.orderItem[1:]

	if v, ok := l.allItem[k]; ok {
		delete(l.allItem, k)
		v2 := v.val
		v.val = nil
		l.pool.Put(v)
		return v2
	}
	return nil
}

func (l *CacheSaveList) GetHeadTick() int64 {
	l.Lock()
	defer l.Unlock()

	if len(l.orderItem) == 0 {
		return 0
	}

	k := l.orderItem[0]
	if v, ok := l.allItem[k]; ok {
		return v.tick
	}

	//不应该会执行到这里
	l.orderItem = l.orderItem[1:]
	return 0
}

func (l *CacheSaveList) Count() int {
	return len(l.orderItem)
}

//缓存读列表
//可以添加、删除、查找元素、超时删除
//查找：存在时返回值，不存在时返回空；
//超时删除：添加的元素，保存一段时间后删除
//添加：加入列表，设置时间戳
