/**
 * Asset-embed extraction + diffing.
 *
 * Entry bodies reference binary assets two ways:
 *   - Obsidian-style transclusion embeds:  ![[Foo.png]]  /  ![[Foo.png|alt]]
 *   - Standard markdown images:            ![alt](/api/assets/asset/<id>/<file>)
 *
 * Asset *binaries* live outside git (the workspace `.studiograph/assets/`
 * tree for the local backend, or Cloudflare R2), so git history can only ever
 * recover the *reference* — the embed text in the body, not the bytes. These
 * helpers let the write path detect when a whole-body rewrite would drop a
 * reference the prior body had, and let the history tools report which embeds
 * exist at a given revision.
 *
 * Callers pass the markdown body (post-frontmatter). Embed syntax is a body
 * construct; frontmatter is not scanned.
 */
// ![[target]] or ![[target|alias]] — capture the target (pre-pipe).
const TRANSCLUSION_RE = /!\[\[([^\]|]+)(?:\|[^\]]*)?\]\]/g;
// ![alt](url) — capture the url. Stops at the first closing paren; asset
// embed URLs in this app never contain parens.
const MARKDOWN_IMAGE_RE = /!\[[^\]]*\]\(([^)]+)\)/g;
/**
 * Extract every embedded asset reference from a markdown body,
 * de-duplicated, transclusions first then markdown images. Returns the raw
 * target (transclusion target or image URL) so callers can compare
 * references across revisions and surface them to users/agents.
 */
export function extractAssetEmbeds(body) {
    if (!body)
        return [];
    const out = [];
    const seen = new Set();
    const push = (ref) => {
        const trimmed = ref.trim();
        if (!trimmed || seen.has(trimmed))
            return;
        seen.add(trimmed);
        out.push(trimmed);
    };
    let m;
    TRANSCLUSION_RE.lastIndex = 0;
    while ((m = TRANSCLUSION_RE.exec(body)) !== null)
        push(m[1]);
    MARKDOWN_IMAGE_RE.lastIndex = 0;
    while ((m = MARKDOWN_IMAGE_RE.exec(body)) !== null)
        push(m[1]);
    return out;
}
/**
 * The canonical, render-safe markdown embed for an asset: `![filename](url)`.
 * This is exactly what the editor inserts on drop/paste
 * (web FormattingPalette), so any agent-placed embed that uses this form is
 * guaranteed to render. Agents must NOT invent `![[filename]]` transclusion
 * placeholders — those don't resolve to a stored asset and render as dead text.
 */
export function assetEmbed(filename, url) {
    return `![${filename}](${url})`;
}
/**
 * References present in `before` but absent from `after` — i.e. embeds a
 * body rewrite would drop. Set semantics on the raw reference string.
 */
export function droppedAssetEmbeds(before, after) {
    const beforeRefs = extractAssetEmbeds(before);
    if (beforeRefs.length === 0)
        return [];
    const afterRefs = new Set(extractAssetEmbeds(after));
    return beforeRefs.filter((ref) => !afterRefs.has(ref));
}
/**
 * Strip a leading YAML frontmatter block (`---\n…\n---`) so embed extraction
 * runs against the body only. Returns the input unchanged when there is no
 * frontmatter. Mirrors the lightweight frontmatter sniff the history tools
 * already use, avoiding a full markdown parse for a read-only report.
 */
export function stripFrontmatter(fileContent) {
    return fileContent.replace(/^---\s*\n[\s\S]*?\n---\s*\n?/, '');
}
// Three path segments after /api/assets/ (type/id/filename). New-scheme URLs
// have only two (assetId/filename), so they never match — the migration is
// idempotent against already-rewritten content. Segments stop at the chars
// that terminate a URL in markdown/YAML: whitespace, ) " ' ].
const LEGACY_ASSET_URL_RE = /\/api\/assets\/([^/\s)"'\]]+)\/([^/\s)"'\]]+)\/([^/\s)"'\]]+)/g;
/** Every legacy `/api/assets/{type}/{id}/{filename}` reference in a file,
 *  de-duplicated by URL. Pass the RAW file (frontmatter + body). */
export function extractLegacyAssetUrls(fileContent) {
    if (!fileContent)
        return [];
    const out = [];
    const seen = new Set();
    let m;
    LEGACY_ASSET_URL_RE.lastIndex = 0;
    while ((m = LEGACY_ASSET_URL_RE.exec(fileContent)) !== null) {
        const url = m[0];
        if (seen.has(url))
            continue;
        seen.add(url);
        out.push({ url, type: m[1], id: m[2], filename: m[3], oldKey: `${m[1]}/${m[2]}/${m[3]}` });
    }
    return out;
}
//# sourceMappingURL=embeds.js.map