"use strict";

exports.__esModule = true;
exports.exportServiceMocks = exportServiceMocks;
var _http = require("@wix/bex-utils/@wix/ambassador-fedinfra-exportservice-v1-export-async-job/http");
var _types = require("@wix/bex-utils/@wix/ambassador-fedinfra-exportservice-v1-export-async-job/types");
var _InMemoryBackend = require("../InMemoryBackend");
var _events = require("events");
var _chance = require("chance");
var _isHttpError = require("../util/isHttpError");
function exportServiceMocks(whenRequest) {
  const chance = new _chance.Chance();
  const events = new _events.EventEmitter();
  const buildExportAsyncJob = (params = {}) => {
    const {
      createDate = new Date(),
      updateDate = createDate,
      ...rest
    } = params;
    return {
      id: chance.guid(),
      status: _types.Status.INITIALIZED,
      ...rest,
      data: {
        iterationsCount: 0,
        processedItemsCount: 0,
        ...rest.data
      },
      createDate,
      updateDate
    };
  };
  const be = new _InMemoryBackend.InMemoryBackend({
    createOne: () => buildExportAsyncJob(),
    itemKey: item => item.id,
    total: 0
  });
  async function simulateJobIterations(initialJob) {
    let job = initialJob;
    try {
      const maxIterationsCount = 4;
      while (((_job$data = job.data) == null ? void 0 : _job$data.iterationsCount) != null && job.data.iterationsCount < maxIterationsCount) {
        var _job$data, _job$data$query, _job$data$query2;
        await new Promise(resolve => setTimeout(resolve, 100));
        const paging = ((_job$data$query = job.data.query) == null ? void 0 : _job$data$query.paging) ?? ((_job$data$query2 = job.data.query) == null ? void 0 : _job$data$query2.cursorPaging);
        job = {
          ...job,
          status: _types.Status.PROCESSING,
          data: {
            ...job.data,
            iterationsCount: job.data.iterationsCount + 1,
            processedItemsCount: (job.data.processedItemsCount ?? 0) + ((paging == null ? void 0 : paging.limit) ?? 0)
          }
        };
        await Promise.all(events.listeners('processing').map(fn => fn(job)));
        await be.update(job);
      }
      const completedJobOverrides = events.listeners('jobCompleted').reduce((prev, current) => ({
        ...prev,
        ...current(job)
      }), {});
      await be.update({
        ...job,
        status: _types.Status.FINISHED,
        ...completedJobOverrides,
        data: {
          ...job.data,
          ...completedJobOverrides.data
        }
      });
      const beforeUpdateSignedUrlOverrides = (await Promise.all(events.listeners('beforeUpdateSignedUrl').map(async f => (await f(job)) ?? {}))).reduce((prev, current) => ({
        ...prev,
        ...current
      }), {});
      await be.update({
        ...job,
        status: _types.Status.FINISHED,
        ...beforeUpdateSignedUrlOverrides,
        data: {
          ...job.data,
          signedUrl: '/export.csv',
          ...beforeUpdateSignedUrlOverrides.data
        }
      });
    } catch (e) {
      await be.update({
        ...job,
        status: _types.Status.FAILED,
        data: {
          ...job.data,
          error: {
            applicationError: {
              code: e.message
            },
            ...e
          }
        }
      });
    }
  }
  return {
    mocks: [whenRequest(_http.createExportAsyncJob).reply(async data => {
      try {
        const paging = data.query.paging ?? data.query.cursorPaging;
        if ((paging == null ? void 0 : paging.limit) == null) {
          throw new Error('ExportServiceMocks: paging.limit is required');
        }
        const job = buildExportAsyncJob({
          data
        });
        await Promise.all(events.listeners('beforeCreateJob').map(fn => fn(job)));
        await be.push([job]);
        await Promise.all(events.listeners('jobCreated').map(fn => fn(job)));
        simulateJobIterations(job);
        return {
          status: 200,
          data: {
            job
          }
        };
      } catch (e) {
        console.error(e);
        if ((0, _isHttpError.isHttpError)(e) && e.response) {
          return {
            status: e.response.status,
            data: e.response.data
          };
        }
        return {
          status: 504,
          data: {}
        };
      }
    }).persist(), whenRequest(_http.getExportAsyncJob).reply(200, async data => {
      const job = be.get(data.jobId);
      await Promise.all(events.listeners('beforeGetJob').map(fn => fn(job)));
      return {
        __applicationErrorsType: {},
        job
      };
    }).persist()],
    be,
    events
  };
}
//# sourceMappingURL=exportServiceMocks.js.map