// 用語のブレを洗う。
//
// PLaMo は文脈のない断片で多義語を取り違える。この世界では
//   Roll     = 名誉録（サイコロを「振る」ではない）
//   rank cap = 階級上限（cap は帽子ではない）
//   hand     = 雇い人
//   stand    = 段（階級上限の一段）
//   the yard = 需品係の庭
//   stage    = 段階（舞台装置ではない）
// といった具合に決まっている。原文にその語があり、訳文に誤った読みが
// 出ているものだけを挙げる（訳文だけを見て置換すると巻き添えが出る）。
import fs from 'fs';

const RULES = [
  { term: /\bRoll\b/, bad: /振る/, good: '名誉録', note: 'Roll = 名誉録' },
  { term: /rank cap|rank-cap/i, bad: /階級帽|ランクキャップ|階級の帽/, good: '階級上限', note: 'cap = 上限' },
  { term: /\bhand(s)?\b/, bad: /手の書/, good: '雇い人の書', note: 'book of hands = 雇い人の書' },
  { term: /\bstand(s)?\b/, bad: /舞台装置|立札|スタンド/, good: '段', note: 'stand = 段' },
  { term: /\bstage(s)?\b/, bad: /舞台装置/, good: '段階', note: 'stage = 段階' },
  { term: /\byard\b/, bad: /ヤード|ドリルヤード/, good: '需品係の庭', note: 'the yard = 需品係の庭' },
  { term: /\bBarracks\b/, bad: /バラックス/, good: '兵舎', note: 'Barracks = 兵舎' },
  { term: /\bmimic(s)?\b/i, bad: /模倣する|模倣者|擬態生物/, good: 'ミミック', note: 'mimic = ミミック' },
  { term: /\bsending\b/, bad: /送電/, good: '送り', note: 'sending = 送り' },
  { term: /\bquarter(s)?\b/, bad: /四半期/, good: '象限', note: '技能ツリーの quarter = 象限' },
  { term: /\bchest(s)?\b/, bad: /胸板|胸の/, good: '櫃', note: 'chest = 櫃' },
  { term: /\bleg(s)?\b/, bad: /脚で緩んだ/, good: '区間', note: 'road leg = 区間' },
  { term: /\bwork(s)?\b/, bad: /作業ターン/, good: '増築', note: 'guild work = 増築' },
  { term: /\bdrill yard\b/i, bad: /ドリルヤード/, good: '訓練場', note: 'drill yard = 訓練場' },
];

const tm = JSON.parse(fs.readFileSync('tm.json', 'utf8'));
const ov = JSON.parse(fs.readFileSync('overrides.json', 'utf8'));
const src = fs.readFileSync('app/game/index.html', 'utf8');

// いまのゲームに出てくる原文だけを対象にする（死んだ訳を直しても意味がない）
const live = s => src.includes(s);

const hits = [];
for (const en in tm) {
  if (ov[en] !== undefined) continue;          // 手訳済みは触らない
  const ja = String(tm[en]);
  if (!/[ぁ-んァ-ヴ一-龯]/.test(ja)) continue;
  for (const r of RULES) {
    if (!r.term.test(en) || !r.bad.test(ja)) continue;
    hits.push({ en, ja, note: r.note, live: live(en) });
    break;
  }
}
const liveHits = hits.filter(h => h.live);
console.log(`用語のブレ: ${hits.length} 件（うち今のゲームに出るもの ${liveHits.length} 件）\n`);
const byNote = {};
for (const h of liveHits) byNote[h.note] = (byNote[h.note] || 0) + 1;
Object.entries(byNote).sort((a, b) => b[1] - a[1]).forEach(([k, v]) => console.log(`  ${String(v).padStart(3)}件  ${k}`));
console.log();
liveHits.slice(0, 30).forEach(h => {
  console.log(`[${h.note}]`);
  console.log(`  ${h.en.slice(0, 96)}`);
  console.log(`  → ${h.ja.slice(0, 96)}`);
});
fs.writeFileSync('termhits.json', JSON.stringify(liveHits, null, 1));
