text: "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