"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get ASC () {
        return ASC;
    },
    get DESC () {
        return DESC;
    },
    get createPriorityMap () {
        return createPriorityMap;
    }
});
const _number = require("../../helpers/number");
const _function = require("../../helpers/function");
const _errors = require("../../helpers/errors");
const ASC = 'asc';
const DESC = 'desc';
const ORDER_MAP = new Map([
    [
        ASC,
        [
            -1,
            1
        ]
    ],
    [
        DESC,
        [
            1,
            -1
        ]
    ]
]);
const DEFAULT_ERROR_PRIORITY_EXISTS = (priority)=>`The priority '${priority}' is already declared in a map.`;
const DEFAULT_ERROR_PRIORITY_NAN = (priority)=>`The priority '${priority}' is not a number.`;
function createPriorityMap({ errorPriorityExists, errorPriorityNaN } = {}) {
    const priorityMap = new Map();
    errorPriorityExists = (0, _function.isFunction)(errorPriorityExists) ? errorPriorityExists : DEFAULT_ERROR_PRIORITY_EXISTS;
    errorPriorityNaN = (0, _function.isFunction)(errorPriorityNaN) ? errorPriorityNaN : DEFAULT_ERROR_PRIORITY_NAN;
    /**
   * Adds items to priority map. Throws an error if `priority` is not a number or if is already added.
   *
   * @param {number} priority The priority for adding item.
   * @param {*} item The adding item.
   */ function addItem(priority, item) {
        if (!(0, _number.isNumeric)(priority)) {
            (0, _errors.throwWithCause)(errorPriorityNaN(priority));
        }
        if (priorityMap.has(priority)) {
            (0, _errors.throwWithCause)(errorPriorityExists(priority));
        }
        priorityMap.set(priority, item);
    }
    /**
   * Gets items from the passed map in a ASC or DESC order of priorities.
   *
   * @param {string} [order] The order for getting items. ASC is an default.
   * @returns {*}
   */ function getItems(order = ASC) {
        const [left, right] = ORDER_MAP.get(order) || ORDER_MAP.get(ASC);
        return [
            ...priorityMap
        ]// we want to be sure we sort over a priority key
        // if we are sure we can remove custom compare function
        // then we should replace next line with a default `.sort()`
        .sort((a, b)=>a[0] < b[0] ? left : right).map((item)=>item[1]);
    }
    return {
        addItem,
        getItems
    };
}
