package com.gzzm.lobster.guardrails;

import com.gzzm.lobster.tool.ToolResult;
import com.gzzm.lobster.common.ToolResultStatus;

import java.util.List;
import java.util.regex.Pattern;

/**
 * ClaimConsistencyChecker —— Claim 一致性检测器 /
 * Detects assistant claims unsupported by tool evidence.
 *
 * <p>当 assistant 正文出现「已读取/已保存/已生成」等完成性声明，但本轮没有任何
 * 对应工具返回 {@code ok} 时，触发告警，runtime 会在下一轮追加系统纠偏提示。
 */
public class ClaimConsistencyChecker {

    // "已" 后可选 "经"/"完成"，匹配 "已生成 / 已经生成 / 已完成写入" 等自然说法
    private static final Pattern CLAIM_WRITE =
            Pattern.compile("已(?:经|完成)?(?:写入|写回|保存|生成|创建|提交|发送|发出|回写)");
    private static final Pattern CLAIM_READ =
            Pattern.compile("已(?:经|完成)?(?:读取|读完|查阅|核对|确认|浏览)");

    public CheckResult check(String assistantText, List<ToolResult> currentTurnResults) {
        if (assistantText == null || assistantText.isEmpty()) return CheckResult.pass();
        boolean hasOkResult = false;
        if (currentTurnResults != null) {
            for (ToolResult r : currentTurnResults) {
                if (r.getStatus() == ToolResultStatus.ok) { hasOkResult = true; break; }
            }
        }
        if (hasOkResult) return CheckResult.pass();
        if (CLAIM_WRITE.matcher(assistantText).find()) {
            return new CheckResult(Severity.WARN,
                    "Detected write-claim without any successful tool result in this turn");
        }
        if (CLAIM_READ.matcher(assistantText).find()) {
            return new CheckResult(Severity.WARN,
                    "Detected read-claim without any successful tool result in this turn");
        }
        return CheckResult.pass();
    }

    public enum Severity { PASS, WARN, BLOCK }

    public static final class CheckResult {
        private final Severity severity;
        private final String reason;

        public CheckResult(Severity severity, String reason) {
            this.severity = severity; this.reason = reason;
        }

        public static CheckResult pass() { return new CheckResult(Severity.PASS, null); }

        public Severity getSeverity() { return severity; }
        public String getReason() { return reason; }
        public boolean isPass() { return severity == Severity.PASS; }
    }
}
