import { execFileSync } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import path from "node:path";

import { describe, expect, it } from "vitest";

const repoRoot = path.resolve(__dirname, "..", "..");

function listTrackedSourceFiles() {
  return execFileSync("git", ["ls-files"], {
    cwd: repoRoot,
    encoding: "utf8",
  })
    .split(/\r?\n/)
    .map((file) => file.trim())
    .filter(Boolean)
    .filter((file) => existsSync(path.join(repoRoot, file)))
    .filter((file) => /\.(?:ts|js|tsx|jsx|mjs|cjs)$/.test(file))
    .filter((file) => !/(\.test\.|\.spec\.)/.test(file))
    .filter((file) => !file.startsWith("src/mocks/"));
}

function findPromptLeakFiles() {
  const promptLeakPatterns = [
    /(?:const|export const)\s+\w*(?:SYSTEM_PROMPT|PROMPT_REQUIREMENTS|PROMPT_EXAMPLE|BASE_PROMPT)\w*\s*=/,
    /role:\s*["']system["'][\s\S]{0,120}content:\s*["'`][\u4e00-\u9fff]/,
    /content:\s*["'`]你是[\s\S]{0,120}(?:JSON|采购|1688|LLM|模型)/,
  ];

  return listTrackedSourceFiles().filter((file) => {
    const content = readFileSync(path.join(repoRoot, file), "utf8");
    return promptLeakPatterns.some((pattern) => pattern.test(content));
  });
}

describe("prompt store only guard", () => {
  it("keeps LLM prompt bodies out of tracked source files", () => {
    expect(findPromptLeakFiles()).toEqual([]);
  });
});
