import fs from "node:fs/promises";
import fss from "node:fs";
import path from "node:path";
import matter from "gray-matter";
import { KnowledgeWriter } from "../../knowledge/writer.js";
import { debug } from "../core/logger.js";
/**
 * 新增知识条目。
 * 根据类型生成对应的模板内容，保存到草稿目录或正式目录。
 * @param input - 新增知识条目输入
 * @param config - 项目配置
 * @returns 新增结果，包含文件路径和消息
 */
export async function addKnowledge(input, config) {
    debug("知识管理", `新增知识条目「${input.title}」[${input.type}]`);
    const knowledgeDir = getProjectKnowledgeDir(config);
    const fileName = `${path.basename(input.title)}.md`; // basename 防止路径穿越
    // 确定保存位置
    const typeDir = getTypeDirectory(input.type);
    const draftsDir = path.join(knowledgeDir, "drafts");
    const targetDir = input.save_to_drafts !== false
        ? draftsDir
        : path.join(knowledgeDir, typeDir);
    // 确保目录存在
    await fs.mkdir(targetDir, { recursive: true });
    const filePath = path.join(targetDir, fileName);
    // 检查文件是否已存在
    if (fss.existsSync(filePath)) {
        return {
            success: false,
            file_path: filePath,
            is_draft: input.save_to_drafts !== false,
            message: `文件已存在: ${filePath}，请使用 sf_knowledge_update 更新`,
        };
    }
    // 生成内容
    const content = generateKnowledgeContent(input);
    await fs.writeFile(filePath, content, "utf-8");
    const enrichment_guide = input.auto_enrich !== false
        ? buildEnrichmentGuide(input)
        : undefined;
    debug("知识管理", `知识条目已保存到 ${filePath}`);
    return {
        success: true,
        file_path: filePath,
        is_draft: input.save_to_drafts !== false,
        message: input.save_to_drafts !== false
            ? `知识条目草稿已保存到: ${filePath}\n人工 review 后可移至正式目录: ${path.join(knowledgeDir, typeDir, fileName)}`
            : `知识条目已保存到: ${filePath}`,
        enrichment_guide,
    };
}
/**
 * 更新已有的知识条目。
 * 更新前自动创建备份，支持修改触发条件、状态、决策规则和验收标准。
 * @param input - 更新输入参数
 * @param knowledgeIndex - 知识索引管理器
 * @param config - 项目配置
 * @returns 更新结果，包含文件路径和备份路径
 */
export async function updateKnowledge(input, knowledgeIndex, _config) {
    debug("知识管理", `更新知识条目「${input.entry_name}」`);
    const entry = knowledgeIndex.getEntry(input.entry_name)
        ?? knowledgeIndex.getAllEntries().global.find((e) => e.name === input.entry_name)
        ?? knowledgeIndex.getAllEntries().project.find((e) => e.name === input.entry_name);
    if (!entry) {
        debug("知识管理", `未找到知识条目「${input.entry_name}」`);
        return {
            success: false,
            file_path: "",
            backup_path: "",
            message: `未找到知识条目: ${input.entry_name}`,
        };
    }
    const filePath = entry.file_path;
    // 维度6: 知识目录隔离 — 禁止更新 core/ 只读目录中的条目
    if (KnowledgeWriter.isCorePath(filePath)) {
        debug("知识管理", `「${input.entry_name}」位于 core/ 只读目录，禁止自动更新`);
        return {
            success: false,
            file_path: filePath,
            backup_path: "",
            message: `知识隔离: "${entry.name}" 位于 core/ 只读目录，禁止自动更新。需人工手动维护`,
        };
    }
    if (!fss.existsSync(filePath)) {
        return {
            success: false,
            file_path: filePath,
            backup_path: "",
            message: `文件不存在: ${filePath}`,
        };
    }
    // 读取并解析文件
    const raw = await fs.readFile(filePath, "utf-8");
    const { data: frontmatter, content: body } = matter(raw);
    // 创建备份
    const backupDir = path.join(path.dirname(filePath), ".backups");
    await fs.mkdir(backupDir, { recursive: true });
    const backupPath = path.join(backupDir, `${entry.name}-${Date.now()}.md`);
    await fs.writeFile(backupPath, raw, "utf-8");
    // 应用更新
    let updated = false;
    if (input.updates.when_triggers) {
        frontmatter.when = input.updates.when_triggers;
        updated = true;
    }
    if (input.updates.status) {
        frontmatter.status = input.updates.status;
        updated = true;
    }
    let newBody = body;
    if (input.updates.add_decision_rules?.length) {
        const rulesSection = input.updates.add_decision_rules
            .map((r) => `- ${r}`)
            .join("\n");
        if (newBody.includes("## 决策规则")) {
            newBody = newBody.replace(/## 决策规则\n/, `## 决策规则\n${rulesSection}\n`);
        }
        else {
            newBody += `\n\n## 决策规则\n${rulesSection}\n`;
        }
        updated = true;
    }
    if (input.updates.add_acceptance_criteria?.length) {
        const acSection = input.updates.add_acceptance_criteria
            .map((ac, i) => `- [AC-${String(i + 1).padStart(2, "0")}] ${ac}`)
            .join("\n");
        if (newBody.includes("## 验收项")) {
            newBody = newBody.replace(/## 验收项\n/, `## 验收项\n${acSection}\n`);
        }
        else {
            newBody += `\n\n## 验收项\n${acSection}\n`;
        }
        updated = true;
    }
    if (!updated) {
        return {
            success: false,
            file_path: filePath,
            backup_path: backupPath,
            message: "未提供任何更新内容",
        };
    }
    // 写入更新后的文件
    const output = matter.stringify(newBody, frontmatter);
    await fs.writeFile(filePath, output, "utf-8");
    debug("知识管理", `知识条目「${input.entry_name}」已更新，备份: ${backupPath}`);
    return {
        success: true,
        file_path: filePath,
        backup_path: backupPath,
        message: `知识条目已更新: ${filePath}\n备份: ${backupPath}`,
    };
}
// ── 辅助函数 ──
/**
 * 获取项目知识库目录路径。
 * @param config - 项目配置
 * @returns 知识库目录的绝对路径
 */
function getProjectKnowledgeDir(config) {
    const projectDir = config._projectPath ?? process.cwd();
    return path.join(projectDir, ".soloforge", "knowledge");
}
/**
 * 根据知识类型获取存储目录名。
 * @param type - 知识条目类型
 * @returns 目录名
 */
function getTypeDirectory(type) {
    const map = {
        pattern: "patterns/temp",
        procedure: "procedures",
        pipeline_procedure: "procedures",
        domain: "domain",
        acceptance_template: "acceptance_templates",
        review_rule: "review_rules",
    };
    return map[type] ?? "procedures";
}
/**
 * 生成知识条目的 frontmatter 文本。
 * @param input - 新增知识条目输入
 * @returns frontmatter 文本
 */
function generateFrontmatter(input) {
    return `---
name: ${input.title}
type: ${input.type}
when: "${input.when_triggers}"
scope: [${input.scope.join(", ")}]
products: ["*"]
---`;
}
/**
 * 生成知识条目的完整内容（frontmatter + body）。
 * 根据类型选择对应的 body 生成器。
 * @param input - 新增知识条目输入
 * @returns 完整的 Markdown 文件内容
 */
function generateKnowledgeContent(input) {
    const fm = generateFrontmatter(input);
    const generators = {
        pattern: () => generatePatternBody(input),
        domain: () => generateDomainBody(input),
        procedure: () => generateProcedureBody(input),
        pipeline_procedure: () => generatePipelineBody(input),
        review_rule: () => generateReviewRuleBody(input),
        acceptance_template: () => generateAcceptanceBody(input),
    };
    const gen = generators[input.type] ?? generators.pattern;
    return `${fm}\n\n${gen()}\n`;
}
/**
 * 生成 pattern 类型知识条目的 body 内容。
 * @param input - 新增知识条目输入
 * @returns body 文本
 */
function generatePatternBody(input) {
    const rules = input.decision_rules
        ? input.decision_rules.split("\n").filter(Boolean).map((r) => `- ${r}`).join("\n")
        : "- (待补充决策规则)";
    return `## 决策规则
${rules}

## 验收项
- [AC-01] (待补充验收标准)`;
}
/**
 * 生成 domain 类型知识条目的 body 内容。
 * @param input - 新增知识条目输入
 * @returns body 文本
 */
function generateDomainBody(input) {
    const rules = input.decision_rules
        ? input.decision_rules.split("\n").filter(Boolean).map((r) => `${r}`).join("\n\n")
        : "(待补充业务规则)";
    return `## 业务规则
${rules}

## 约束条件
- (待补充约束条件)

## 例外情况
- (待补充例外情况)

## 关联模式
- (待补充关联模式)`;
}
/**
 * 生成 procedure 类型知识条目的 body 内容。
 * @param input - 新增知识条目输入
 * @returns body 文本
 */
function generateProcedureBody(_input) {
    return `## 适用场景
(待补充适用场景描述)

## 步骤
1. (待补充步骤)

## 检查点
- [ ] (待补充检查点)

## 注意事项
- (待补充注意事项)`;
}
/**
 * 生成 pipeline_procedure 类型知识条目的 body 内容。
 * @param input - 新增知识条目输入
 * @returns body 文本
 */
function generatePipelineBody(input) {
    return `# ${input.title}

### 第1步：定义阶段
(待补充阶段描述)
产出保存到：.soloforge/output/01-产出.md
工具：sf_classify, sf_expand

### 第2步：执行阶段
(待补充阶段描述)
工具：sf_verify`;
}
/**
 * 生成 review_rule 类型知识条目的 body 内容。
 * @param input - 新增知识条目输入
 * @returns body 文本
 */
function generateReviewRuleBody(input) {
    const code = input.title.toUpperCase().replace(/-/g, "").slice(0, 3);
    return `## ${code}-01: (待补充规则标题)
pattern: /(待补充正则)/
severity: warning
scope: ${input.scope.join(", ")}
description: (待补充规则描述)`;
}
/**
 * 生成 acceptance_template 类型知识条目的 body 内容。
 * @param input - 新增知识条目输入
 * @returns body 文本
 */
function generateAcceptanceBody(input) {
    return `# ${input.title}

## 1. (待补充章节标题)
(待补充内容)

## 2. (待补充章节标题)
(待补充内容)`;
}
// ── 自动丰富指南 ──
/**
 * 从标题中提取可读的主题名称。
 * @param title - 知识条目标题（含连字符/下划线）
 * @returns 格式化后的主题名称
 */
function extractTopicFromTitle(title) {
    return title.split(/[-_]/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
}
/**
 * 根据知识类型构建对应的自动丰富指南。
 * @param input - 新增知识条目输入
 * @returns 自动丰富指南
 */
function buildEnrichmentGuide(input) {
    const builders = {
        pattern: () => buildPatternGuide(input),
        domain: () => buildDomainGuide(input),
        procedure: () => buildProcedureGuide(input),
        pipeline_procedure: () => buildPipelineGuide(input),
        review_rule: () => buildReviewRuleGuide(input),
        acceptance_template: () => buildAcceptanceGuide(input),
    };
    return builders[input.type]();
}
/**
 * 构建 pattern 类型的自动丰富指南。
 * @param input - 新增知识条目输入
 * @returns 丰富指南
 */
function buildPatternGuide(input) {
    const topic = extractTopicFromTitle(input.title);
    return {
        entry_name: input.title,
        type: "pattern",
        overview: `从行业最佳实践中提取"${topic}"领域的决策规则和验收标准。规则应具体、可操作、可验证，覆盖安全、性能、可维护性等维度。`,
        steps: [
            {
                step_number: 1,
                action: `搜索"${topic}"的最佳实践、常见陷阱和反模式`,
                search_queries: [`${topic} best practices software development`, `${topic} common mistakes anti-patterns`, `${topic} production checklist enterprise`],
                focus_areas: ["常见错误", "性能陷阱", "安全风险", "可维护性"],
            },
            {
                step_number: 2,
                action: `从搜索结果中提取至少 5 条决策规则`,
                search_queries: [`${topic} coding guidelines ${input.scope.join(" ")}`, `${topic} design patterns enterprise java`],
                focus_areas: ["规则具体性", "可操作性", "互斥性"],
            },
            {
                step_number: 3,
                action: "为每条规则设计可验证的验收标准（AC）",
                focus_areas: ["可自动化检查", "明确的通过/失败标准"],
            },
            {
                step_number: 4,
                action: `调用 sf_knowledge_update 将探索到的规则和验收项写入文件`,
                focus_areas: ["使用 add_decision_rules 和 add_acceptance_criteria 参数"],
            },
        ],
        authoritative_sources: [
            "OWASP Cheat Sheet Series — 安全相关模式",
            "Google Engineering Practices (google.github.io/eng-practices) — 代码评审实践",
            "Alibaba Java Development Manual — Java 开发最佳实践",
            "Martin Fowler's Patterns Catalog — 设计模式",
            "Microsoft API Guidelines — API 设计模式",
        ],
        completeness_thresholds: [
            { field: "decision_rules", minimum: 5 },
            { field: "acceptance_criteria", minimum: 3 },
        ],
        update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_decision_rules=[规则1, 规则2, ...], add_acceptance_criteria=[标准1, 标准2, ...])`,
    };
}
/**
 * 构建 domain 类型的自动丰富指南。
 * @param input - 新增知识条目输入
 * @returns 丰富指南
 */
function buildDomainGuide(input) {
    const topic = extractTopicFromTitle(input.title);
    return {
        entry_name: input.title,
        type: "domain",
        overview: `研究"${topic}"领域的行业标准和监管要求，提取业务规则、约束条件、例外情况和关联模式。`,
        steps: [
            {
                step_number: 1,
                action: `搜索"${topic}"领域的行业标准和法规要求`,
                search_queries: [`${topic} business rules industry standard`, `${topic} compliance regulatory requirements`, `${topic} domain driven design`],
                focus_areas: ["行业法规", "合规要求", "业务约束"],
            },
            {
                step_number: 2,
                action: "提取核心业务规则（什么必须为真、什么不能发生）",
                focus_areas: ["业务规则", "状态约束", "数据完整性"],
            },
            {
                step_number: 3,
                action: "识别技术约束和操作约束",
                focus_areas: ["性能约束", "安全约束", "容量约束"],
            },
            {
                step_number: 4,
                action: "列举例外场景和边界条件",
                focus_areas: ["边缘场景", "特殊条件", "豁免情况"],
            },
            {
                step_number: 5,
                action: `调用 sf_knowledge_update 将探索到的内容写入文件`,
                focus_areas: ["使用 add_decision_rules 写入业务规则"],
            },
        ],
        authoritative_sources: [
            "OWASP — 安全相关领域",
            "PCI-DSS — 支付相关领域",
            "GDPR / 个人信息保护法 — 数据隐私领域",
            "Domain-Driven Design (Eric Evans) — 领域建模",
            "行业特定标准（HIPAA/SOX/ISO 27001）",
        ],
        completeness_thresholds: [
            { field: "business_rules", minimum: 6 },
            { field: "constraints", minimum: 4 },
            { field: "exceptions", minimum: 2 },
            { field: "related_patterns", minimum: 1 },
        ],
        update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_decision_rules=[业务规则1, 业务规则2, ...])`,
    };
}
/**
 * 构建 procedure 类型的自动丰富指南。
 * @param input - 新增知识条目输入
 * @returns 丰富指南
 */
function buildProcedureGuide(input) {
    const topic = extractTopicFromTitle(input.title);
    return {
        entry_name: input.title,
        type: "procedure",
        overview: `研究"${topic}"的标准操作流程，拆分为有序步骤、检查点和注意事项。`,
        steps: [
            {
                step_number: 1,
                action: `搜索"${topic}"的标准流程和行业实践`,
                search_queries: [`${topic} standard procedure workflow`, `${topic} step by step guide`, `${topic} operational best practices`],
                focus_areas: ["标准流程", "关键步骤", "验证节点"],
            },
            {
                step_number: 2,
                action: "将流程拆分为有序的原子步骤",
                focus_areas: ["步骤顺序", "步骤原子性", "输入输出明确"],
            },
            {
                step_number: 3,
                action: "在关键节点设计检查点（验证门禁）",
                focus_areas: ["质量门禁", "可验证条件"],
            },
            {
                step_number: 4,
                action: "识别常见陷阱和注意事项",
                focus_areas: ["常见错误", "风险点", "最佳实践"],
            },
            {
                step_number: 5,
                action: `调用 sf_knowledge_update 将步骤内容写入文件`,
                focus_areas: ["使用 add_decision_rules 写入步骤和注意事项"],
            },
        ],
        authoritative_sources: [
            "Google SRE Book — 运维流程实践",
            "CI/CD Pipeline Best Practices — 部署发布流程",
            "Git Workflow Guides — 代码管理流程",
            "OWASP Secure Development Lifecycle — 安全开发流程",
        ],
        completeness_thresholds: [
            { field: "steps", minimum: 5 },
            { field: "checkpoints", minimum: 3 },
            { field: "notes", minimum: 3 },
        ],
        update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_decision_rules=[步骤内容, 注意事项, ...])`,
    };
}
/**
 * 构建 pipeline_procedure 类型的自动丰富指南。
 * @param input - 新增知识条目输入
 * @returns 丰富指南
 */
function buildPipelineGuide(input) {
    const topic = extractTopicFromTitle(input.title);
    return {
        entry_name: input.title,
        type: "pipeline_procedure",
        overview: `设计"${topic}"的多阶段流水线，明确每个阶段的工具、产出和检查点。`,
        steps: [
            {
                step_number: 1,
                action: `搜索"${topic}"相关的流水线或工作流设计`,
                search_queries: [`${topic} pipeline workflow design`, `${topic} multi-phase process`],
                focus_areas: ["阶段划分", "阶段边界", "入口/出口条件"],
            },
            {
                step_number: 2,
                action: "为每个阶段映射具体的 SoloForge 工具（sf_classify, sf_expand, sf_verify 等）",
                focus_areas: ["工具选择", "工具参数"],
            },
            {
                step_number: 3,
                action: "定义每个阶段的产出物和保存路径",
                focus_areas: ["产出格式", "路径规范"],
            },
            {
                step_number: 4,
                action: `调用 sf_knowledge_update 将阶段内容写入文件`,
                focus_areas: ["使用 add_decision_rules 写入阶段定义"],
            },
        ],
        authoritative_sources: [
            "CI/CD Pipeline Best Practices",
            "Google SRE Release Engineering",
            "GitHub Actions Workflow Patterns",
        ],
        completeness_thresholds: [
            { field: "phases", minimum: 3 },
            { field: "tools_per_phase", minimum: 1 },
        ],
        update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_decision_rules=[阶段定义1, 阶段定义2, ...])`,
    };
}
/**
 * 构建 review_rule 类型的自动丰富指南。
 * @param input - 新增知识条目输入
 * @returns 丰富指南
 */
function buildReviewRuleGuide(input) {
    const topic = extractTopicFromTitle(input.title);
    return {
        entry_name: input.title,
        type: "review_rule",
        overview: `研究"${topic}"相关的代码质量问题，定义正则匹配规则、严重级别和描述。规则需覆盖安全、性能、质量维度。`,
        steps: [
            {
                step_number: 1,
                action: `搜索"${topic}"相关的常见代码质量问题和安全漏洞`,
                search_queries: [`${topic} code review checklist`, `${topic} static analysis rules`, `${topic} common vulnerabilities patterns`],
                focus_areas: ["代码异味", "安全漏洞模式", "性能反模式"],
            },
            {
                step_number: 2,
                action: "为每个问题定义可匹配的正则表达式（pattern）",
                focus_areas: ["正则精确性", "误报率控制", "覆盖变体"],
            },
            {
                step_number: 3,
                action: "分配严重级别（critical/warning/info）并编写描述",
                focus_areas: ["严重度合理性", "描述清晰性", "修复建议"],
            },
            {
                step_number: 4,
                action: `调用 sf_knowledge_update 将规则写入文件`,
                focus_areas: ["使用 add_decision_rules 写入规则定义"],
            },
        ],
        authoritative_sources: [
            "OWASP Code Review Guide — 安全审查规则",
            "ESLint / PMD / Checkstyle Rule Catalogs — 静态分析规则",
            "Google Style Guides — 代码风格规则",
            "Alibaba Java Development Manual — Java 规则",
            "SonarQube Rule Definitions — 质量规则",
        ],
        completeness_thresholds: [
            { field: "rules", minimum: 5 },
            { field: "critical_rules", minimum: 1 },
        ],
        update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_decision_rules=[规则定义1, 规则定义2, ...])`,
    };
}
/**
 * 构建 acceptance_template 类型的自动丰富指南。
 * @param input - 新增知识条目输入
 * @returns 丰富指南
 */
function buildAcceptanceGuide(input) {
    const topic = extractTopicFromTitle(input.title);
    return {
        entry_name: input.title,
        type: "acceptance_template",
        overview: `研究"${topic}"的行业标准验收门禁，设计覆盖安全、性能、质量维度的验收清单，每个验收项需包含可执行的检查命令。`,
        steps: [
            {
                step_number: 1,
                action: `搜索"${topic}"的质量门禁和验收标准`,
                search_queries: [`${topic} acceptance criteria checklist`, `${topic} quality gate verification`, `${topic} production readiness review`],
                focus_areas: ["安全验收", "性能验收", "功能验收", "合规验收"],
            },
            {
                step_number: 2,
                action: "为每个验收项设计可执行的检查命令（grep/find/test 命令）",
                focus_areas: ["命令可执行性", "结果可判定性"],
            },
            {
                step_number: 3,
                action: "确保验收项覆盖安全（≥2项）和质量（≥2项）维度",
                focus_areas: ["安全覆盖", "质量覆盖", "独立性"],
            },
            {
                step_number: 4,
                action: `调用 sf_knowledge_update 将验收项写入文件`,
                focus_areas: ["使用 add_acceptance_criteria 写入验收项"],
            },
        ],
        authoritative_sources: [
            "OWASP ASVS (Application Security Verification Standard) — 安全验收",
            "Microsoft Security Development Lifecycle — 安全开发验收",
            "Google Engineering Practices — 代码质量验收",
            "IEEE Software Quality Standards — 软件质量标准",
        ],
        completeness_thresholds: [
            { field: "acceptance_criteria", minimum: 10 },
            { field: "security_acs", minimum: 2 },
            { field: "check_commands", minimum: 10 },
        ],
        update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_acceptance_criteria=[验收项1, 验收项2, ...])`,
    };
}
//# sourceMappingURL=knowledge_writer.js.map