/**
 * Low-level helpers for MaterializedViewService.
 *
 * Provides in-memory property reader construction, shard OID partitioning,
 * and the legacy shard-to-tree-entry mapper.
 *
 * P5-LEGACY: _shardToEntry and buildInMemoryPropertyReader exist to support
 * callers that persist via persistIndexTree(). Will be removed when callers
 * migrate to IndexStorePort.writeShards().
 *
 * @module domain/services/MaterializedViewHelpers
 */
import { MetaShard } from "../artifacts/MetaShard.js";
import { EdgeShard } from "../artifacts/EdgeShard.js";
import { LabelShard } from "../artifacts/LabelShard.js";
import { PropertyShard } from "../artifacts/PropertyShard.js";
import { ReceiptShard } from "../artifacts/ReceiptShard.js";
import IndexError from "../errors/IndexError.js";
import PropertyIndexReader from "./index/PropertyIndexReader.js";
/** Prefix for property shard paths in the index tree. */
export const PROPS_PREFIX = 'props_';
// ── In-memory property reader ─────────────────────────────────────────────────
/**
 * Creates a PropertyIndexReader backed by an in-memory tree map.
 */
export function buildInMemoryPropertyReader(tree, codec) {
    const propShardOids = new Map();
    for (const path of Object.keys(tree)) {
        if (path.startsWith(PROPS_PREFIX)) {
            propShardOids.set(path, path);
        }
    }
    // PropertyIndexReader is a .js file with JSDoc types; only `readBlob` is
    // called at runtime. The narrower in-memory object satisfies the runtime
    // contract of IndexStoragePort, so this seam cast is safe.
    const storage = {
        /** Reads a shard blob from the in-memory tree map. */
        readBlob: (oid) => Promise.resolve(tree[oid]),
    }; // nosemgrep: ts-no-double-cast -- 0025A; nosemgrep: ts-no-unknown-outside-adapters -- 0025B
    const reader = new PropertyIndexReader({ storage, codec });
    reader.setup(Object.fromEntries(propShardOids));
    return reader;
}
// ── Shard OID partitioning ────────────────────────────────────────────────────
/**
 * Partitions shard OID entries into index vs property buckets.
 */
export function partitionShardOids(shardOids) {
    const indexOids = new Map();
    const propOids = new Map();
    for (const [path, oid] of Object.entries(shardOids)) {
        if (path.startsWith(PROPS_PREFIX)) {
            propOids.set(path, oid);
        }
        else {
            indexOids.set(path, oid);
        }
    }
    return {
        indexOids: Object.fromEntries(indexOids),
        propOids: Object.fromEntries(propOids),
    };
}
// ── Shard → tree entry ────────────────────────────────────────────────────────
/**
 * Maps an IndexShard to its tree path and serializable payload.
 *
 * P5-LEGACY: Duplicates IndexShardEncodeTransform._encode() in
 * infrastructure. Exists only to support _encodeShardsToTree() for
 * the applyDiff() legacy path. Dies when IncrementalIndexUpdater
 * is migrated to IndexStorePort.
 */
export function shardToEntry(shard) {
    if (shard instanceof MetaShard) {
        return {
            path: `meta_${shard.shardKey}.cbor`,
            payload: { nodeToGlobal: shard.nodeToGlobal, nextLocalId: shard.nextLocalId, alive: shard.alive },
        };
    }
    if (shard instanceof EdgeShard) {
        return { path: `${shard.direction}_${shard.shardKey}.cbor`, payload: shard.buckets };
    }
    if (shard instanceof LabelShard) {
        return { path: 'labels.cbor', payload: shard.labels };
    }
    if (shard instanceof PropertyShard) {
        return { path: `props_${shard.shardKey}.cbor`, payload: shard.entries };
    }
    if (shard instanceof ReceiptShard) {
        return {
            path: 'receipt.cbor',
            payload: {
                version: shard.version,
                nodeCount: shard.nodeCount,
                labelCount: shard.labelCount,
                shardCount: shard.shardCount,
            },
        };
    }
    throw new IndexError(`MaterializedViewService: unknown IndexShard type (shardKey=${shard.shardKey})`, // nosemgrep: ts-no-unknown-outside-adapters -- 0025B
    { code: 'E_MATERIALIZED_VIEW_UNKNOWN_SHARD', context: { shardKey: shard.shardKey } });
}
