package eino

import (
	"context"

	"github.com/cloudwego/eino/compose"
)

// CheckpointKV 是 compose checkpoint 的最小持久化后端：朴素的键值 + 软缺失语义。
// 生产由 bus 的 JetStream KV（*bus.KVHandle）实现（结构化满足，无需反向依赖 bus）；
// 单测用内存桩。键 = checkPointID（dispatcher 取 task_id），值 = compose 序列化的图状态。
type CheckpointKV interface {
	Get(ctx context.Context, key string) (val []byte, ok bool, err error)
	Put(ctx context.Context, key string, val []byte) error
	Delete(ctx context.Context, key string) error
}

// checkpointStore 把 CheckpointKV 适配成 Eino compose.CheckPointStore（Get/Set），
// 并实现可选的 CheckPointDeleter（Delete）——审批恢复 / 终态后显式删 checkpoint，
// 避免 KV 堆积；桶级 TTL 再兜底清理被遗弃的中断（审批人始终不处理）。
//
// 中断模型：审批节点 compose.Interrupt 时，compose 把整图状态写进本 store（key=task_id）；
// dispatcher 据此置 waiting 并返回（释放 goroutine）。决定到达后以同 key 重入图 → 从断点恢复。
type checkpointStore struct{ kv CheckpointKV }

func newCheckpointStore(kv CheckpointKV) *checkpointStore { return &checkpointStore{kv: kv} }

// Get 读 checkpoint；不存在返回 (nil,false,nil)，由 compose 视作"无断点、全新执行"。
func (s *checkpointStore) Get(ctx context.Context, checkPointID string) ([]byte, bool, error) {
	return s.kv.Get(ctx, checkPointID)
}

// Set 持久化一次中断的图状态。
func (s *checkpointStore) Set(ctx context.Context, checkPointID string, checkPoint []byte) error {
	return s.kv.Put(ctx, checkPointID, checkPoint)
}

// Delete 显式清理 checkpoint（实现 compose 的可选 CheckPointDeleter，结构化匹配）。
func (s *checkpointStore) Delete(ctx context.Context, checkPointID string) error {
	return s.kv.Delete(ctx, checkPointID)
}

// 编译期确认实现了 compose.CheckPointStore（Get/Set）。Delete 经结构化断言由运行时识别。
var _ compose.CheckPointStore = (*checkpointStore)(nil)
