import StreamingIndexStoragePort from "../../ports/StreamingIndexStoragePort.js";
import WarpError from "../../domain/errors/WarpError.js";
import { decodeCasPayloadPointer, encodeCasPayloadPointer, readPayloadBlob, writePayloadBlob, } from "./CasPayloadPointer.js";
export class CasIndexStorageAdapter extends StreamingIndexStoragePort {
    _blobPort;
    _treePort;
    _refPort;
    _blobStorage;
    constructor(options) {
        super();
        this._blobPort = options.blobPort;
        this._treePort = options.treePort;
        this._refPort = options.refPort;
        this._blobStorage = options.blobStorage;
    }
    async writeBlob(content) {
        const bytes = typeof content === 'string' ? new TextEncoder().encode(content) : content;
        return await writePayloadBlob({
            blobPort: this._blobPort,
            blobStorage: this._blobStorage,
            bytes,
        });
    }
    async readBlob(oid) {
        return await readPayloadBlob({
            blobPort: this._blobPort,
            blobStorage: this._blobStorage,
            oid,
        });
    }
    async writeBlobStream(source, options) {
        const storageOid = await this._blobStorage.storeStream(source, options);
        return await this._blobPort.writeBlob(encodeCasPayloadPointer(storageOid));
    }
    readBlobStream(oid) {
        const adapter = this;
        return {
            async *[Symbol.asyncIterator]() {
                const pointerBytes = await adapter._blobPort.readBlob(oid);
                const storageOid = decodeCasPayloadPointer(pointerBytes);
                if (storageOid === null) {
                    throw new WarpError(`Inline index payload blob ${oid} requires the substrate migration compatibility policy`, 'E_LEGACY_SUBSTRATE_DISABLED');
                }
                for await (const chunk of adapter._blobStorage.retrieveStream(storageOid)) {
                    yield chunk;
                }
            },
        };
    }
    async writeTree(entries) {
        return await this._treePort.writeTree(entries);
    }
    async readTreeOids(treeOid) {
        return await this._treePort.readTreeOids(treeOid);
    }
    async updateRef(ref, oid) {
        await this._refPort.updateRef(ref, oid);
    }
    async readRef(ref) {
        return await this._refPort.readRef(ref);
    }
}
