// Code generated by NodeGenerator. DO NOT EDIT.

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

import (
	"sync/atomic"
	"unsafe"
)

// BEW is a cache entry that provide the following features:
//
// 1. Base
//
// 2. Expiration
//
// 3. Weight
type BEW[K comparable, V any] struct {
	key       K
	value     V
	prev      *BEW[K, V]
	next      *BEW[K, V]
	prevExp   *BEW[K, V]
	nextExp   *BEW[K, V]
	expiresAt atomic.Int64
	weight    uint32
	state     atomic.Uint32
	queueType uint8
}

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

	return n
}

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

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

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

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

func (n *BEW[K, V]) Prev() Node[K, V] {
	return n.prev
}

func (n *BEW[K, V]) SetPrev(v Node[K, V]) {
	if v == nil {
		n.prev = nil
		return
	}
	n.prev = (*BEW[K, V])(v.AsPointer())
}

func (n *BEW[K, V]) Next() Node[K, V] {
	return n.next
}

func (n *BEW[K, V]) SetNext(v Node[K, V]) {
	if v == nil {
		n.next = nil
		return
	}
	n.next = (*BEW[K, V])(v.AsPointer())
}

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

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

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

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

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

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

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

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

func (n *BEW[K, V]) RefreshableAt() int64 {
	panic("not implemented")
}

func (n *BEW[K, V]) CASRefreshableAt(old, new int64) bool {
	panic("not implemented")
}

func (n *BEW[K, V]) SetRefreshableAt(new int64) {
	panic("not implemented")
}

func (n *BEW[K, V]) IsFresh(now int64) bool {
	return true
}

func (n *BEW[K, V]) Weight() uint32 {
	return n.weight
}

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

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

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

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

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

func (n *BEW[K, V]) GetQueueType() uint8 {
	return n.queueType
}

func (n *BEW[K, V]) SetQueueType(queueType uint8) {
	n.queueType = queueType
}

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

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

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

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

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

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