/**
 * TODO: 已设计但未接入运行时的治理机制。待治理管线完善后启用。
 *
 * 能力状态覆盖存储 — 持久化人工确认的能力状态变更。
 * P2-8 范围: 显式更新（dry_run + 证据校验 + 人工确认），不自动改状态。
 * 存储: JSON 文件，原子写入，路径绑定 stateDir。
 */
import fs from "node:fs";
import path from "node:path";
import { debug } from "../core/logger.js";
import { safeJsonParse } from "../core/helpers.js";
/** 合法的状态转移映射表 */
const VALID_TRANSITIONS = {
    enforced: ["advisory", "removed"],
    advisory: ["enforced", "experimental", "removed"],
    experimental: ["advisory", "removed"],
    removed: ["experimental"],
};
/** 能力状态覆盖存储 — 管理人工确认的能力状态变更 */
export class CapabilityStateStore {
    filePath;
    overrides = [];
    loaded = false;
    /**
     * 创建能力状态覆盖存储实例。
     * @param stateDir - 状态目录路径，覆盖数据将存储在此目录下
     */
    constructor(stateDir) {
        this.filePath = path.join(stateDir, "capability-state-overrides.json");
        if (!fs.existsSync(stateDir)) {
            fs.mkdirSync(stateDir, { recursive: true });
        }
        debug("能力状态存储", "初始化完成，数据路径: " + this.filePath);
    }
    /** 确保数据已从磁盘加载 */
    ensureLoaded() {
        if (this.loaded)
            return;
        this.loaded = true;
        try {
            const data = fs.readFileSync(this.filePath, "utf-8");
            const raw = safeJsonParse(data);
            // 运行时验证：确保是数组且元素含必要字段
            if (!Array.isArray(raw)) {
                debug("能力状态存储", "状态文件格式无效(非数组)，重置为空");
                this.overrides = [];
                return;
            }
            this.overrides = raw.filter((item) => typeof item === "object" && item !== null && "policy_id" in item);
        }
        catch (e) {
            debug("能力状态存储", "加载状态文件失败(预期行为: 文件不存在) —", e);
            this.overrides = [];
        }
    }
    /** 持久化当前数据到磁盘（原子写入） */
    persist() {
        const tmpPath = `${this.filePath}.tmp`;
        fs.writeFileSync(tmpPath, JSON.stringify(this.overrides, null, 2));
        fs.renameSync(tmpPath, this.filePath);
    }
    /**
     * 获取策略的生效状态。优先返回最新覆盖的状态，无覆盖时返回默认状态。
     * @param policyId - 策略 ID
     * @param defaultState - 默认状态（无覆盖记录时使用）
     * @returns 该策略的生效状态
     */
    getEffectiveState(policyId, defaultState) {
        this.ensureLoaded();
        let latest;
        for (const o of this.overrides) {
            if (o.policy_id === policyId)
                latest = o;
        }
        return latest ? latest.new_state : defaultState;
    }
    /**
     * 列出所有状态覆盖记录。
     * @returns 覆盖记录列表（深拷贝）
     */
    list() {
        this.ensureLoaded();
        return this.overrides.map((o) => ({ ...o, evidence_ids: [...o.evidence_ids] }));
    }
    /**
     * 校验状态更新请求的合法性。
     * 检查策略存在性、转移合法性、证据匹配、人工确认等条件。
     * @param request - 状态更新请求
     * @param currentState - 当前状态
     * @param capabilityId - 能力 ID（未找到时为 null）
     * @param escapeReports - 已有的逃逸报告列表（用于证据校验）
     * @returns 校验结果，包含错误列表和生成的覆盖记录
     */
    validate(request, currentState, capabilityId, escapeReports) {
        const errors = [];
        if (!capabilityId) {
            errors.push(`policy_id ${request.policy_id} not found in capability registry`);
        }
        if (request.target_state === currentState) {
            errors.push(`target_state (${request.target_state}) same as current state, no change needed`);
        }
        if (capabilityId && request.target_state !== currentState) {
            const allowed = VALID_TRANSITIONS[currentState];
            if (!allowed.includes(request.target_state)) {
                errors.push(`${currentState} → ${request.target_state} is not a valid transition (allowed: ${allowed.join(", ")})`);
            }
        }
        if (request.evidence_ids.length === 0) {
            errors.push("at least one evidence_id is required");
        }
        const matchedEvidence = request.evidence_ids.filter((eid) => escapeReports.some((r) => r.escape_id === eid && r.policy_id === request.policy_id));
        const unmatchedEvidence = request.evidence_ids.filter((eid) => !matchedEvidence.includes(eid));
        if (request.evidence_ids.length > 0 && unmatchedEvidence.length > 0) {
            errors.push(`evidence_ids not found for policy ${request.policy_id}: ${unmatchedEvidence.join(", ")}`);
        }
        if (!request.confirm) {
            errors.push("confirm=true required for state changes; human confirmation mandatory");
        }
        if (!request.confirmed_by.trim()) {
            errors.push("confirmed_by is required");
        }
        if (!request.reason.trim()) {
            errors.push("reason is required");
        }
        const evidenceMatched = matchedEvidence.length > 0;
        const override = {
            policy_id: request.policy_id,
            previous_state: currentState,
            new_state: request.target_state,
            reason: request.reason,
            evidence_ids: [...request.evidence_ids],
            confirmed_by: request.confirmed_by,
            updated_at: new Date().toISOString(),
        };
        return {
            policy_id: request.policy_id,
            capability_id: capabilityId,
            previous_state: currentState,
            new_state: request.target_state,
            updated: false,
            dry_run: request.dry_run,
            validation_errors: errors,
            evidence_matched: evidenceMatched,
            override: errors.length === 0 ? override : null,
        };
    }
    /**
     * 校验并应用状态更新请求。校验通过且非演练模式时，持久化覆盖记录。
     * @param request - 状态更新请求
     * @param currentState - 当前状态
     * @param capabilityId - 能力 ID（未找到时为 null）
     * @param escapeReports - 已有的逃逸报告列表（用于证据校验）
     * @returns 更新结果，包含是否实际更新
     */
    apply(request, currentState, capabilityId, escapeReports) {
        this.ensureLoaded();
        const result = this.validate(request, currentState, capabilityId, escapeReports);
        if (result.validation_errors.length > 0 || request.dry_run || !result.override) {
            if (request.dry_run) {
                debug("能力状态存储", `演练模式，策略 ${request.policy_id} 校验完成（未持久化）`);
            }
            if (result.validation_errors.length > 0) {
                debug("能力状态存储", `策略 ${request.policy_id} 校验失败，错误数: ${result.validation_errors.length}`);
            }
            return result;
        }
        this.overrides.push(result.override);
        this.persist();
        debug("能力状态存储", `策略 ${request.policy_id} 状态已更新 ${currentState} → ${request.target_state}`);
        return { ...result, updated: true };
    }
    /**
     * 清空所有覆盖记录并持久化。
     */
    clear() {
        this.overrides = [];
        this.loaded = true;
        this.persist();
        debug("能力状态存储", "已清空所有覆盖记录");
    }
}
//# sourceMappingURL=capability_state_store.js.map