#!/usr/bin/env node
/**
 * mentor-journal-store — персист журнала переговоров наставника (F-C2-4) + вердикта.
 * Формат журнала = action-journal (jsonl-цепь + head-подпись [action-journal.mjs:83-119]);
 * файлы mentor-journal-<sess>.jsonl/.head + mentor-verdict-<sess>.json. Atomic temp→rename
 * (зеркало saveTaskId F-C1 / writeAtomic plan-lock). Node fs — НЕ Write-tool.
 */
import fsDefault from 'node:fs';
import { assertSafeSessionId } from './action-journal.mjs';

function paths(runtimeDir, sessionId) {
  assertSafeSessionId(sessionId);
  const sep = runtimeDir.endsWith('/') ? '' : '/';
  return {
    jsonl: `${runtimeDir}${sep}mentor-journal-${sessionId}.jsonl`,
    head: `${runtimeDir}${sep}mentor-journal-${sessionId}.head`,
    verdict: `${runtimeDir}${sep}mentor-verdict-${sessionId}.json`,
  };
}

function writeAtomic(path, data, fsImpl) {
  const tmp = `${path}.tmp`;
  fsImpl.writeFileSync(tmp, data);
  fsImpl.renameSync(tmp, path);
}

/** Загрузить цепь переговоров (F-C2-4: ИМЕННО это идёт в onPlanWrite.journalEntries). */
export function loadMentorJournal({ sessionId, runtimeDir, fsImpl = fsDefault }) {
  const { jsonl, head } = paths(runtimeDir, sessionId);
  let entries = [];
  try {
    entries = String(fsImpl.readFileSync(jsonl, 'utf8')).split('\n').filter(Boolean).map((l) => JSON.parse(l));
  } catch (e) {
    if (e && e.code === 'ENOENT') return { entries: [], headSig: null };
    throw e;
  }
  let headSig = null;
  try { headSig = String(fsImpl.readFileSync(head, 'utf8')).trim() || null; } catch { headSig = null; }
  return { entries, headSig };
}

/** Персист полной цепи (выход onPlanWrite.journal = {entries, headSig}) — atomic. */
export function persistMentorJournal({ journal, sessionId, runtimeDir, fsImpl = fsDefault }) {
  const { jsonl, head } = paths(runtimeDir, sessionId);
  const lines = (journal && Array.isArray(journal.entries) ? journal.entries : []).map((e) => JSON.stringify(e)).join('\n');
  writeAtomic(jsonl, lines ? lines + '\n' : '', fsImpl);
  writeAtomic(head, String((journal && journal.headSig) ?? ''), fsImpl);
}

/** Персист/чтение последнего вердикта наставника (потребитель — freeze-gate в пути печати). */
export function persistMentorVerdict({ record, sessionId, runtimeDir, fsImpl = fsDefault }) {
  writeAtomic(paths(runtimeDir, sessionId).verdict, JSON.stringify(record ?? null), fsImpl);
}
export function loadMentorVerdict({ sessionId, runtimeDir, fsImpl = fsDefault }) {
  try { return JSON.parse(fsImpl.readFileSync(paths(runtimeDir, sessionId).verdict, 'utf8')); }
  catch (e) { if (e && e.code === 'ENOENT') return null; throw e; }
}
