"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.aTagsArray = exports.TAGS = void 0;
exports.createBackend = createBackend;
exports.default = createTagImdb;
exports.withUpdateTagForAccount = exports.withUpdateTag = exports.withQueryTagsForAccount = exports.withQueryTags = exports.withListTagsForAccount = exports.withListTags = exports.withDeleteTag = exports.withCreateTagForAccount = exports.withCreateTag = exports.tagsAPIHttpClientMocks = exports.getUpdateTagErrorMock = exports.getQueryTagsErrorMock = exports.getListTagsForAccountErrorMock = exports.getListTagsErrorMock = exports.getDeleteTagErrorMock = exports.getCreateTagForAccountErrorMock = exports.getCreateTagErrorMock = exports.generateInvalidLongName = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _chance = require("chance");
var _client = require("@wix/fe-essentials/http-client/testkit/client");
var _http = require("@wix/bex-utils/@wix/ambassador-os-tags-v1-tag/http");
var _backend = require("../testkit/backend");
var _HttpErrorMocks = require("./HttpErrorMocks");
var _ExpectedTestError = require("../__tests__/utils/ExpectedTestError");
class ServerError extends _ExpectedTestError.ExpectedTestError {
  constructor(code, message) {
    super(message);
    (0, _defineProperty2.default)(this, "code", void 0);
    this.code = code;
  }
}
const chance = new _chance.Chance();
const aTag = (overrides = {}) => {
  return {
    id: chance.guid(),
    name: chance.word({
      length: 5
    }),
    createdDate: chance.date({
      min: new Date(Date.now() - 365 * 24 * 60 * 60 * 1000),
      max: new Date()
    }),
    ...overrides
  };
};
const aTagsArray = count => Array.from({
  length: count
}, () => aTag());
exports.aTagsArray = aTagsArray;
const generateInvalidLongName = length => chance.string({
  length
});
exports.generateInvalidLongName = generateInvalidLongName;
const TAGS = exports.TAGS = aTagsArray(2);
const buildQueryTagsReply = tags => async ({
  query
}) => {
  var _query$filter, _query$cursorPaging, _query$cursorPaging2;
  const allTags = tags || TAGS;
  const search = query == null || (_query$filter = query.filter) == null || (_query$filter = _query$filter.name) == null ? void 0 : _query$filter.$startsWith;
  const filteredTags = search ? allTags.filter(tag => {
    var _tag$name;
    return (_tag$name = tag.name) == null ? void 0 : _tag$name.toLowerCase().startsWith(search.toLowerCase());
  }) : allTags;
  const limit = (query == null || (_query$cursorPaging = query.cursorPaging) == null ? void 0 : _query$cursorPaging.limit) ?? filteredTags.length;
  const cursorToken = query == null || (_query$cursorPaging2 = query.cursorPaging) == null ? void 0 : _query$cursorPaging2.cursor;
  const offset = cursorToken ? parseInt(atob(cursorToken), 10) : 0;
  const pageItems = filteredTags.slice(offset, offset + limit);
  const nextOffset = offset + limit;
  const hasNext = nextOffset < filteredTags.length;
  return {
    tags: pageItems,
    pagingMetadata: {
      count: pageItems.length,
      cursors: {
        next: hasNext ? btoa(String(nextOffset)) : null
      },
      hasNext,
      total: filteredTags.length
    }
  };
};
const withQueryTags = tags => (0, _client.whenRequest)(_http.queryTags).reply(200, buildQueryTagsReply(tags)).persist();
exports.withQueryTags = withQueryTags;
const withQueryTagsForAccount = tags => (0, _client.whenRequest)(_http.queryTagsForAccount).reply(200, buildQueryTagsReply(tags)).persist();
exports.withQueryTagsForAccount = withQueryTagsForAccount;
const withListTags = tags => withQueryTags(tags);
exports.withListTags = withListTags;
const withListTagsForAccount = tags => withQueryTagsForAccount(tags);
exports.withListTagsForAccount = withListTagsForAccount;
const createTagResponseMock = tag => ({
  __applicationErrorsType: {},
  tag: {
    createdDate: new Date(),
    updatedDate: new Date(),
    ...tag
  }
});
const withCreateTag = mock => (0, _client.whenRequest)(_http.createTag).reply(200, mock || (async ({
  tag
}) => {
  return createTagResponseMock(tag);
})).persist();
exports.withCreateTag = withCreateTag;
const withCreateTagForAccount = mock => (0, _client.whenRequest)(_http.createTagForAccount).reply(200, mock || (async ({
  tag
}) => {
  return createTagResponseMock(tag);
})).persist();
exports.withCreateTagForAccount = withCreateTagForAccount;
const withUpdateTag = () => (0, _client.whenRequest)(_http.updateTag).reply(200, async tag => {
  return tag;
}).persist();
exports.withUpdateTag = withUpdateTag;
const withUpdateTagForAccount = () => (0, _client.whenRequest)(_http.updateTagForAccount).reply(200, async tag => {
  return tag;
}).persist();
exports.withUpdateTagForAccount = withUpdateTagForAccount;
const withDeleteTag = () => (0, _client.whenRequest)(_http.deleteTag).reply(200, async () => {
  return {};
}).persist();
exports.withDeleteTag = withDeleteTag;
const getQueryTagsErrorMock = ({
  code = 'ERR_NETWORK',
  status = 429
} = {}) => (0, _client.whenRequest)(_http.queryTags).reply(200, async () => {
  return new Promise((_resolve, reject) => {
    window.setTimeout(() => {
      reject((0, _HttpErrorMocks.createHttpErrorMock)({
        code,
        status
      }));
    }, 500);
  });
}).persist();
exports.getQueryTagsErrorMock = getQueryTagsErrorMock;
const getListTagsErrorMock = ({
  code = 'ERR_NETWORK',
  status = 429
} = {}) => getQueryTagsErrorMock({
  code,
  status
});
exports.getListTagsErrorMock = getListTagsErrorMock;
const getListTagsForAccountErrorMock = ({
  code = 'ERR_NETWORK',
  status = 429
} = {}) => (0, _client.whenRequest)(_http.queryTagsForAccount).reply(200, async () => {
  return new Promise((_resolve, reject) => {
    setTimeout(() => {
      reject((0, _HttpErrorMocks.createHttpErrorMock)({
        code,
        status
      }));
    }, 500);
  });
}).persist();
exports.getListTagsForAccountErrorMock = getListTagsForAccountErrorMock;
const getCreateTagErrorMock = ({
  code = 'ERR_NETWORK',
  status = 429,
  requestId
} = {}) => (0, _client.whenRequest)(_http.createTag).reply(200, async () => {
  return new Promise((_resolve, reject) => {
    window.setTimeout(() => {
      reject((0, _HttpErrorMocks.createHttpErrorMock)({
        code,
        status,
        requestId
      }));
    }, 500);
  });
}).persist();
exports.getCreateTagErrorMock = getCreateTagErrorMock;
const getCreateTagForAccountErrorMock = ({
  code = 'ERR_NETWORK',
  status = 429
} = {}) => (0, _client.whenRequest)(_http.createTagForAccount).reply(200, async () => {
  return new Promise((_resolve, reject) => {
    window.setTimeout(() => {
      reject((0, _HttpErrorMocks.createHttpErrorMock)({
        code,
        status
      }));
    }, 500);
  });
}).persist();
exports.getCreateTagForAccountErrorMock = getCreateTagForAccountErrorMock;
const getUpdateTagErrorMock = ({
  code,
  status
} = {}) => (0, _client.whenRequest)(_http.updateTag).reply(200, async () => {
  return new Promise((_resolve, reject) => {
    window.setTimeout(() => {
      reject((0, _HttpErrorMocks.createHttpErrorMock)({
        code,
        status
      }));
    }, 500);
  });
}).persist();
exports.getUpdateTagErrorMock = getUpdateTagErrorMock;
const getDeleteTagErrorMock = (code = 'ERR_NETWORK') => (0, _client.whenRequest)(_http.deleteTag).reply(200, async () => {
  return new Promise((_resolve, reject) => {
    window.setTimeout(() => {
      reject(new ServerError(code, 'error'));
    }, 500);
  });
}).persist();
exports.getDeleteTagErrorMock = getDeleteTagErrorMock;
function createTagImdb({
  createdDate = new Date(Date.now() - 365 * 24 * 60 * 60 * 1000),
  updatedDate = createdDate,
  fqdn = 'wix.patterns.dummyservice.v1.dummy_entity',
  ...overrides
} = {}) {
  return {
    createdDate,
    updatedDate,
    fqdn,
    ...overrides
  };
}
function createBackend(tags) {
  return new _backend.InMemoryBackend({
    total: tags.length,
    paginationMode: 'offset',
    delay: {
      min: 100,
      max: 2000
    },
    createOne: index => createTagImdb(tags[index]),
    predicate: query => {
      const filters = query.filters ?? {};
      const {
        fqdn
      } = filters;
      return item => item.fqdn === fqdn;
    },
    orderBy: query => {
      return [...(query.sort ?? [])];
    },
    itemKey: item => item.id
  });
}
const tagsAPIHttpClientMocks = tags => {
  const tagsBackend = createBackend(tags);
  return [(0, _client.whenRequest)(_http.listTags).reply(200, async ({
    fqdn
  }) => {
    return tagsBackend.fetchData({
      filters: {
        fqdn
      },
      limit: tags.length
    }).then(({
      items
    }) => {
      if (fqdn === 'wix.patterns.dummyservice.v1.empty') {
        return {
          tags: []
        };
      } else if (fqdn === 'wix.patterns.dummyservice.v1.over_limit') {
        return {
          tags: aTagsArray(105)
        };
      } else {
        return {
          tags: items
        };
      }
    });
  }).persist(), (0, _client.whenRequest)(_http.queryTags).reply(200, async ({
    fqdn,
    query
  }) => {
    var _query$filter2, _query$cursorPaging3, _query$cursorPaging4;
    if (fqdn === 'wix.patterns.dummyservice.v1.empty') {
      return {
        tags: [],
        pagingMetadata: {
          count: 0,
          cursors: {
            next: null
          },
          hasNext: false
        }
      };
    }
    const allItems = fqdn === 'wix.patterns.dummyservice.v1.over_limit' ? aTagsArray(105) : (await tagsBackend.fetchData({
      filters: {
        fqdn
      },
      limit: 1000
    })).items;
    const search = query == null || (_query$filter2 = query.filter) == null || (_query$filter2 = _query$filter2.name) == null ? void 0 : _query$filter2.$startsWith;
    const filtered = search ? allItems.filter(tag => {
      var _tag$name2;
      return (_tag$name2 = tag.name) == null ? void 0 : _tag$name2.toLowerCase().startsWith(search.toLowerCase());
    }) : allItems;
    const limit = (query == null || (_query$cursorPaging3 = query.cursorPaging) == null ? void 0 : _query$cursorPaging3.limit) ?? filtered.length;
    const cursorToken = query == null || (_query$cursorPaging4 = query.cursorPaging) == null ? void 0 : _query$cursorPaging4.cursor;
    const offset = cursorToken ? parseInt(atob(cursorToken), 10) : 0;
    const pageItems = filtered.slice(offset, offset + limit);
    const nextOffset = offset + limit;
    const hasNext = nextOffset < filtered.length;
    return {
      tags: pageItems,
      pagingMetadata: {
        count: pageItems.length,
        cursors: {
          next: hasNext ? btoa(String(nextOffset)) : null
        },
        hasNext,
        total: filtered.length
      }
    };
  }).persist(), (0, _client.whenRequest)(_http.createTag).reply(200, ({
    tag
  }) => {
    tagsBackend.push([tag]);
    return {
      __applicationErrorsType: {},
      tag
    };
  }).persist(), (0, _client.whenRequest)(_http.updateTag).reply(200, ({
    tag
  }) => {
    tagsBackend.update(tag);
    return {
      tag
    };
  }).persist(), (0, _client.whenRequest)(_http.deleteTag).reply(200, ({
    tagId
  }) => {
    tagsBackend.map.delete(tagId);
  }).persist()];
};
exports.tagsAPIHttpClientMocks = tagsAPIHttpClientMocks;
//# sourceMappingURL=TagsMocks.js.map