package contextkey

import (
	"context"
)

// Key 泛型键对象，封装特定类型的上下文存取
type CtxKey[T any] struct {
	key any // 实际存储的唯一键（通过空结构体保证类型唯一）
}

// NewKey 创建管理特定类型值的键对象（每个调用生成唯一键）
func NewCtxKey[T any]() CtxKey[T] {
	type uniqueKey struct{} // 闭包内部类型确保唯一性
	return CtxKey[T]{key: uniqueKey{}}
}

// WithValue 将值存入context，返回新context
func (k CtxKey[T]) WithValue(ctx context.Context, value T) context.Context {
	//fmt.Printf("WithValue=====>key:%v|addr:%p\n", k.key, &k.key)
	return context.WithValue(ctx, k.key, value)
}

// GetValue 从context中提取值（带类型安全校验）
func (k CtxKey[T]) GetValue(ctx context.Context) (T, bool) {
	//fmt.Printf("GetValue#1=====>key:%v|addr:%p\n", k.key, &k.key)
	v := ctx.Value(k.key)
	if v == nil {
		var zero T
		return zero, false
	}
	//fmt.Printf("GetValue#2=====>key:%v|addr:%p\n", k.key, &k.key)
	t, ok := v.(T)
	return t, ok
}
