import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { GOLDEN_CASES } from './golden/assignment-golden';

/**
 * Golden set 的**防腐**测试 —— 它不跑模型，只保证这份用例集本身不烂掉。
 *
 * ⚠️ 真正的 golden 跑批要调模型（花钱、慢、有波动），**刻意不进 CI**；
 *   但用例集会随代码漂：工具改名了、用例引用的工具已经不存在了 ——
 *   那时跑批会全绿或全红，两种都看不出真相。⇒ 这条测试守的是那个。
 */

const FACTORY = readFileSync(
  join(__dirname, '../src/modules/mcp/mcp-server.factory.ts'),
  'utf8',
);
const ASSIST = readFileSync(
  join(__dirname, '../src/modules/assistant/assistant.service.ts'),
  'utf8',
);

/** 当前真实注册的工具名（MCP 条件注册 + 助手本地工具） */
const REGISTERED = new Set<string>([
  ...[...FACTORY.matchAll(/registerTool\(\s*'([a-z_]+)'/g)].map((m) => m[1]!),
  ...[...ASSIST.matchAll(/tools\.([a-z_]+)\s*=\s*tool\(/g)].map((m) => m[1]!),
]);

describe('Golden set 防腐', () => {
  test('⭐ 注册表本身解析得到（否则下面几条会假绿）', () => {
    expect(REGISTERED.size).toBeGreaterThan(8);
    expect(REGISTERED.has('propose_assignment')).toBe(true);
    expect(REGISTERED.has('get_cohort_attributes')).toBe(true);
  });

  test('🔴 用例引用的每个工具都真的存在（工具改名后用例会静默失效）', () => {
    for (const c of GOLDEN_CASES) {
      for (const t of [...c.mustCall, ...(c.mustNotCall ?? [])]) {
        expect({ case: c.id, tool: t, exists: REGISTERED.has(t) }).toEqual({
          case: c.id,
          tool: t,
          exists: true,
        });
      }
    }
  });

  test('🔴 每条用例都写了 why（⛔ 没有由来的用例半年后没人敢删，只会越攒越多）', () => {
    for (const c of GOLDEN_CASES) {
      expect({ id: c.id, hasWhy: c.why.length > 20 }).toEqual({ id: c.id, hasWhy: true });
    }
  });

  test('⭐ id 不重复（跑批结果按 id 对比，重了就对错行）', () => {
    const ids = GOLDEN_CASES.map((c) => c.id);
    expect(new Set(ids).size).toBe(ids.length);
  });

  test('🔴 mustNotSay 只用于会造成真实损失的说法，⛔ 不锁措辞偏好', () => {
    // ⚠️ 判据：能进这个集合的词，必须是"说了它而事实不成立 → 主管会停止补救"那一类。
    //   ⛔ 「简洁」「专业」这种风格偏好绝不能进 —— 那会让每次文案调整都变成红。
    const allowed = new Set(['已撤销', '已收回', '已经分配好了', '已派下去', 'CL001']);
    for (const c of GOLDEN_CASES) {
      for (const w of c.mustNotSay ?? []) {
        expect({ case: c.id, word: w, allowed: allowed.has(w) }).toEqual({
          case: c.id,
          word: w,
          allowed: true,
        });
      }
    }
  });
});
