#!/usr/bin/env node
/**
 * artifact-from-spec (C1, §5) — спека markdown → {sections, source_sha}.
 * ref = ЯВНЫЙ якорь `## ... {#id}` (P2-2, НЕ слаг заголовка). Пустой раздел отброшен
 * (fail-CLOSE). source_sha — sha256 исходного текста (входит в sealable-объект, SD-1).
 */
import { createHash } from 'node:crypto';

const ANCHOR_RE = /^#{1,6}\s+.*\{#([a-zA-Z0-9._-]+)\}\s*$/;

/** markdown → { sections: { <anchor>: <содержимое раздела> } }. */
export function parseAnchoredSections(md) {
  const lines = String(md == null ? '' : md).split(/\r?\n/);
  const sections = {};
  let curKey = null; let buf = [];
  const flush = () => {
    if (curKey) { const body = buf.join('\n').trim(); if (body) sections[curKey] = body; }
    buf = [];
  };
  for (const line of lines) {
    const m = line.match(ANCHOR_RE);
    const isHeading = /^#{1,6}\s+/.test(line);
    if (m) { flush(); curKey = m[1]; }
    else if (isHeading) { flush(); curKey = null; }   // заголовок без якоря закрывает раздел
    else if (curKey) buf.push(line);
  }
  flush();
  return { sections };
}

/** sealable-объект артефакта: { sections, source_sha }. */
export function buildArtifact(md) {
  const { sections } = parseAnchoredSections(md);
  const source_sha = createHash('sha256').update(String(md == null ? '' : md)).digest('hex');
  return { sections, source_sha };
}
