"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsonrpc_ts_1 = require("@fitbit/jsonrpc-ts");
const fdb_protocol_1 = require("@fitbit/fdb-protocol");
class BulkDataReceiver {
    constructor(bulkData, name) {
        this.bulkData = bulkData;
        this.name = name;
        this.contexts = new Map();
        this.finalizeStream = ({ stream }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            const context = yield this.popStreamContext(stream);
            context.resolve(context.stream.finalize());
        });
        this.abortStream = ({ stream }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            const context = yield this.popStreamContext(stream);
            context.stream.finalize();
            context.reject('Aborted by host');
        });
    }
    receiveFromStream(executor) {
        const stream = this.bulkData.createWriteStream();
        return new Promise((resolve, reject) => {
            const openPromise = executor(stream);
            openPromise.catch((reason) => {
                stream.finalize();
                reject(reason);
            });
            this.contexts.set(stream.token, { openPromise, stream, resolve, reject });
        });
    }
    popStreamContext(token) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const context = this.contexts.get(token);
            if (context !== undefined) {
                try {
                    yield context.openPromise;
                    this.contexts.delete(token);
                    return context;
                }
                catch (_a) { }
            }
            throw new jsonrpc_ts_1.InvalidParams(`Stream token '${token}' does not match any open ${this.name} stream`, { stream: token });
        });
    }
    registerCloserMethods(dispatcher, finalizeMethod, abortMethod) {
        const finalize = abortMethod ? finalizeMethod : `${finalizeMethod}.finalize`;
        const abort = abortMethod || `${finalizeMethod}.abort`;
        dispatcher
            .method(finalize, fdb_protocol_1.FDBTypes.StreamCloseParams, this.finalizeStream)
            .method(abort, fdb_protocol_1.FDBTypes.StreamCloseParams, this.abortStream);
    }
}
exports.default = BulkDataReceiver;
//# sourceMappingURL=BulkDataReceiver.js.map