// Code generated by NodeGenerator. DO NOT EDIT.

// Package node is a generated by the generator.
package node

import (
	"sync/atomic"
	"unsafe"
)

// BER is a cache entry that provide the following features:
//
// 1. Base
//
// 2. Expiration
//
// 3. Refresh
type BER[K comparable, V any] struct {
	key           K
	value         V
	prevExp       *BER[K, V]
	nextExp       *BER[K, V]
	expiresAt     atomic.Int64
	refreshableAt atomic.Int64
	state         atomic.Uint32
}

// NewBER creates a new BER.
func NewBER[K comparable, V any](key K, value V, expiresAt, refreshableAt int64, weight uint32) Node[K, V] {
	n := &BER[K, V]{
		key:   key,
		value: value,
	}
	n.expiresAt.Store(expiresAt)
	n.refreshableAt.Store(refreshableAt)
	n.state.Store(aliveState)

	return n
}

// CastPointerToBER casts a pointer to BER.
func CastPointerToBER[K comparable, V any](ptr unsafe.Pointer) Node[K, V] {
	return (*BER[K, V])(ptr)
}

func (n *BER[K, V]) Key() K {
	return n.key
}

func (n *BER[K, V]) Value() V {
	return n.value
}

func (n *BER[K, V]) AsPointer() unsafe.Pointer {
	return unsafe.Pointer(n)
}

func (n *BER[K, V]) Prev() Node[K, V] {
	panic("not implemented")
}

func (n *BER[K, V]) SetPrev(v Node[K, V]) {
	panic("not implemented")
}

func (n *BER[K, V]) Next() Node[K, V] {
	panic("not implemented")
}

func (n *BER[K, V]) SetNext(v Node[K, V]) {
	panic("not implemented")
}

func (n *BER[K, V]) PrevExp() Node[K, V] {
	return n.prevExp
}

func (n *BER[K, V]) SetPrevExp(v Node[K, V]) {
	if v == nil {
		n.prevExp = nil
		return
	}
	n.prevExp = (*BER[K, V])(v.AsPointer())
}

func (n *BER[K, V]) NextExp() Node[K, V] {
	return n.nextExp
}

func (n *BER[K, V]) SetNextExp(v Node[K, V]) {
	if v == nil {
		n.nextExp = nil
		return
	}
	n.nextExp = (*BER[K, V])(v.AsPointer())
}

func (n *BER[K, V]) HasExpired(now int64) bool {
	return n.ExpiresAt() <= now
}

func (n *BER[K, V]) ExpiresAt() int64 {
	return n.expiresAt.Load()
}

func (n *BER[K, V]) CASExpiresAt(old, new int64) bool {
	return n.expiresAt.CompareAndSwap(old, new)
}

func (n *BER[K, V]) SetExpiresAt(new int64) {
	n.expiresAt.Store(new)
}

func (n *BER[K, V]) RefreshableAt() int64 {
	return n.refreshableAt.Load()
}

func (n *BER[K, V]) CASRefreshableAt(old, new int64) bool {
	return n.refreshableAt.CompareAndSwap(old, new)
}

func (n *BER[K, V]) SetRefreshableAt(new int64) {
	n.refreshableAt.Store(new)
}

func (n *BER[K, V]) IsFresh(now int64) bool {
	return n.IsAlive() && n.RefreshableAt() > now
}

func (n *BER[K, V]) Weight() uint32 {
	return 1
}

func (n *BER[K, V]) IsAlive() bool {
	return n.state.Load() == aliveState
}

func (n *BER[K, V]) IsRetired() bool {
	return n.state.Load() == retiredState
}

func (n *BER[K, V]) Retire() {
	n.state.Store(retiredState)
}

func (n *BER[K, V]) IsDead() bool {
	return n.state.Load() == deadState
}

func (n *BER[K, V]) Die() {
	n.state.Store(deadState)
}

func (n *BER[K, V]) GetQueueType() uint8 {
	panic("not implemented")
}

func (n *BER[K, V]) SetQueueType(queueType uint8) {
	panic("not implemented")
}

func (n *BER[K, V]) InWindow() bool {
	return n.GetQueueType() == InWindowQueue
}

func (n *BER[K, V]) MakeWindow() {
	n.SetQueueType(InWindowQueue)
}

func (n *BER[K, V]) InMainProbation() bool {
	return n.GetQueueType() == InMainProbationQueue
}

func (n *BER[K, V]) MakeMainProbation() {
	n.SetQueueType(InMainProbationQueue)
}

func (n *BER[K, V]) InMainProtected() bool {
	return n.GetQueueType() == InMainProtectedQueue
}

func (n *BER[K, V]) MakeMainProtected() {
	n.SetQueueType(InMainProtectedQueue)
}
