import Transform from "../../domain/stream/Transform.js";
import { MetaShard } from "../../domain/artifacts/MetaShard.js";
import { EdgeShard } from "../../domain/artifacts/EdgeShard.js";
import { LabelShard } from "../../domain/artifacts/LabelShard.js";
import { PropertyShard } from "../../domain/artifacts/PropertyShard.js";
import { ReceiptShard } from "../../domain/artifacts/ReceiptShard.js";
import WarpError from "../../domain/errors/WarpError.js";
/**
 * Stream transform that maps IndexShard instances to [path, bytes] entries.
 *
 * Owns path mapping (domain → Git tree path) AND CBOR encoding.
 * The adapter knows which IndexShard subclass maps to which path.
 * Domain never touches paths.
 *
 * Input:  IndexShard (MetaShard | EdgeShard | LabelShard | PropertyShard | ReceiptShard)
 * Output: [string, Uint8Array] — [Git tree path, CBOR bytes]
 */
export class IndexShardEncodeTransform extends Transform {
    _codec;
    constructor(codec) {
        super();
        if (codec === null || codec === undefined) {
            throw new WarpError('IndexShardEncodeTransform requires a codec', 'E_INVALID_DEPENDENCY');
        }
        this._codec = codec;
    }
    async *apply(source) {
        for await (const shard of source) {
            yield this._encode(shard);
        }
    }
    /**
     * Maps a single IndexShard to [path, bytes].
     */
    _encode(shard) {
        if (shard instanceof MetaShard) {
            return [
                `meta_${shard.shardKey}.cbor`,
                this._codec.encode({
                    nodeToGlobal: shard.nodeToGlobal,
                    nextLocalId: shard.nextLocalId,
                    alive: shard.alive,
                }),
            ];
        }
        if (shard instanceof EdgeShard) {
            return [
                `${shard.direction}_${shard.shardKey}.cbor`,
                this._codec.encode(shard.buckets),
            ];
        }
        if (shard instanceof LabelShard) {
            return [
                'labels.cbor',
                this._codec.encode(shard.labels),
            ];
        }
        if (shard instanceof PropertyShard) {
            return [
                `props_${shard.shardKey}.cbor`,
                this._codec.encode(shard.entries),
            ];
        }
        if (shard instanceof ReceiptShard) {
            return [
                'receipt.cbor',
                this._codec.encode({
                    version: shard.version,
                    nodeCount: shard.nodeCount,
                    labelCount: shard.labelCount,
                    shardCount: shard.shardCount,
                }),
            ];
        }
        throw new WarpError('Unknown IndexShard type', 'E_UNKNOWN_SHARD');
    }
}
