package com.gzzm.lobster.context;

import net.cyan.thunwind.annotation.OQL;
import net.cyan.thunwind.annotation.OQLUpdate;
import net.cyan.thunwind.dao.GeneralDao;

import java.util.Date;
import java.util.List;

/**
 * CompactionEventDao —— 摘要事件持久化 / Compaction event persistence.
 *
 * <p>主要用作 {@link LlmSummarizer} 的幂等缓存索引：按 (threadId, keyHash) 查回旧 summaryRef。
 *
 * <p>清理策略：当前**无任何调用方主动清理**——表会随长对话累积。可对接：
 * <ul>
 *   <li>thread archive 钩子：调 {@link #deleteByThread} 同步删 thread 的所有摘要事件</li>
 *   <li>定时任务（cron）：调 {@link #deleteOlderThan} 删超过 N 天的事件（同时要清 ContentStore 里的 summaryRef）</li>
 * </ul>
 * 注意：{@link CompactionEvent#getSummaryRef()} 指向的 ContentStore 文件是惰性的，
 * 删 DAO 行后要单独走 {@code FileSystemContentStore.delete(ref)}，否则磁盘上会留孤儿。
 * 推荐先 {@link #listByThread} → 拿到 summaryRef 列表 → 删盘 → 再删表。
 */
public abstract class CompactionEventDao extends GeneralDao {

    @OQL("select e from CompactionEvent e where e.threadId=:1 and e.keyHash=:2")
    public abstract CompactionEvent findByKey(String threadId, String keyHash) throws Exception;

    @OQL("select e from CompactionEvent e where e.threadId=:1 order by e.createTime desc")
    public abstract List<CompactionEvent> listByThread(String threadId) throws Exception;

    /** 列出 createTime 早于 cutoff 的事件，用于定期归档/清理. */
    @OQL("select e from CompactionEvent e where e.createTime<?1 order by e.createTime asc")
    public abstract List<CompactionEvent> listOlderThan(Date cutoff) throws Exception;

    /** 删除指定 thread 的所有事件；调用方应先取 summaryRef 列表去 ContentStore 清理对应文件. */
    @OQLUpdate("delete from CompactionEvent where threadId=?1")
    public abstract int deleteByThread(String threadId) throws Exception;

    /** 删除 createTime 早于 cutoff 的所有事件；同样要先清盘. */
    @OQLUpdate("delete from CompactionEvent where createTime<?1")
    public abstract int deleteOlderThan(Date cutoff) throws Exception;
}
