import { ObjectUtils } from "@sankhyalabs/core";
export class ArrayRepository {
  constructor(equalsFunction) {
    this._list = [];
    this._listCopy = [];
    this._listLastUpdate = 0;
    this._listCopyLastUpdate = 0;
    this._equalsFunction = equalsFunction;
  }
  async load(filterFunction, sortingFunction, offset, limit) {
    let result = [].concat(this._list);
    if (filterFunction != undefined) {
      result = this._list.filter(item => filterFunction(item));
    }
    if (sortingFunction != undefined) {
      result = result.sort(sortingFunction);
    }
    const count = result.length;
    if (limit != undefined) {
      const start = offset || 0;
      const end = limit ? start + limit : result.length;
      result = result.slice(start, end);
    }
    return Promise.resolve({ result, count });
  }
  async distict(itemProcessor) {
    const processedItems = [];
    let hasEmpty = false;
    for (const item of this._list) {
      const processedItem = itemProcessor(item);
      if (processedItem == undefined) {
        continue;
      }
      if (processedItem.value == undefined) {
        hasEmpty = true;
        continue;
      }
      processedItems.push(processedItem);
    }
    if (hasEmpty) {
      processedItems.push({ key: "", value: null });
    }
    return Promise.resolve(new Map(processedItems.map(item => [item.key, item.value])));
  }
  async push(items) {
    this.updateList([...this._list, ...items]);
  }
  async clear() {
    this.updateList([]);
  }
  async delete(items) {
    const list = this._list.filter(item => {
      for (const removed of items) {
        if (this._equalsFunction(item, removed)) {
          return false;
        }
      }
      return true;
    });
    this.updateList(list);
  }
  async update(items) {
    const list = this._list.map(existingItem => {
      const newItem = items.find(newItem => this._equalsFunction(existingItem, newItem));
      return newItem == undefined ? existingItem : newItem;
    });
    this.updateList(list);
  }
  async insert(itemReference, items) {
    const itemPosition = this._list.indexOf(itemReference);
    if (itemPosition == -1) {
      this.push(items);
      return;
    }
    const list = this._list.slice(0, itemPosition).concat(items).concat(this._list.slice(itemPosition));
    this.updateList(list);
  }
  isOperating() {
    return true;
  }
  async isEmpty() {
    return Promise.resolve(this._list.length === 0);
  }
  async count() {
    return Promise.resolve(this._list.length);
  }
  getFromCache() {
    if (this._listLastUpdate > this._listCopyLastUpdate) {
      this._listCopyLastUpdate = this._listLastUpdate;
      this._listCopy = ObjectUtils.copy(this._list);
    }
    return this._listCopy;
  }
  updateList(newList) {
    this._list = newList;
    this._listLastUpdate = Date.now();
  }
}
