/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
// Append value along the keyPath to object. For example assign(deposits, ['1337', '31337'], [{depositId:1}]) will create
// deposits = {1337:{31337:[{depositId:1}]}}. Note that if the path into the object exists then this will append. This
import { __assign, __spreadArray } from "tslib";
// function respects the destination type; if it is an object then deep merge and if an array effectively will push.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function assign(obj, keyPath, value) {
    var lastKeyIndex = keyPath.length - 1;
    for (var i = 0; i < lastKeyIndex; ++i) {
        var key = keyPath[i];
        if (!(key in obj)) {
            obj[key] = {};
        }
        obj = obj[key];
    }
    // If the object at the deep path does not exist then set to the value.
    if (!obj[keyPath[lastKeyIndex]] || typeof obj[keyPath[lastKeyIndex]] == "string") {
        obj[keyPath[lastKeyIndex]] = value;
    }
    // If the object at the deep path is an array then append array wise.
    else if (Array.isArray(value)) {
        obj[keyPath[lastKeyIndex]] = __spreadArray(__spreadArray([], obj[keyPath[lastKeyIndex]], true), value, true);
    }
    // If the value is false bool then set to false. This special case is needed as {...false} = {} which causes issues.
    else if (value === false) {
        obj[keyPath[lastKeyIndex]] = false;
    }
    // If the object at the deep path is an object then append object wise.
    else {
        obj[keyPath[lastKeyIndex]] = __assign(__assign({}, obj[keyPath[lastKeyIndex]]), value);
    }
}
// Trims `obj` by deleting `value` and all empty dictionaries produced from that deletion.
export function deleteFromJson(obj, keyPath) {
    var lastKeyIndex = keyPath.length - 1;
    var _obj = obj; // Copy the pointer.
    for (var i = 0; i < lastKeyIndex; ++i) {
        var key = keyPath[i];
        _obj = obj[key];
    }
    delete _obj[keyPath[lastKeyIndex]];
    if (lastKeyIndex !== 0 && Object.values(_obj).length === 0) {
        deleteFromJson(obj, keyPath.slice(0, lastKeyIndex));
    }
}
// Refactor to be more generalized with N props
export function groupObjectCountsByThreeProps(objects, primaryProp, secondaryProp, tertiaryProp) {
    return objects.reduce(function (result, obj) {
        var _a, _b;
        result[obj[primaryProp]] = (_a = result[obj[primaryProp]]) !== null && _a !== void 0 ? _a : {};
        result[obj[primaryProp]][obj[secondaryProp]] = (_b = result[obj[primaryProp]][obj[secondaryProp]]) !== null && _b !== void 0 ? _b : {};
        var existingCount = result[obj[primaryProp]][obj[secondaryProp]][obj[tertiaryProp]];
        result[obj[primaryProp]][obj[secondaryProp]][obj[tertiaryProp]] =
            existingCount === undefined ? 1 : existingCount + 1;
        return result;
    }, {});
}
export function groupObjectCountsByTwoProps(objects, primaryProp, getSecondaryProp) {
    return objects.reduce(function (result, obj) {
        var _a;
        result[obj[primaryProp]] = (_a = result[obj[primaryProp]]) !== null && _a !== void 0 ? _a : {};
        var existingCount = result[obj[primaryProp]][getSecondaryProp(obj)];
        result[obj[primaryProp]][getSecondaryProp(obj)] = existingCount === undefined ? 1 : existingCount + 1;
        return result;
    }, {});
}
export function groupObjectCountsByProp(objects, getProp) {
    return objects.reduce(function (result, obj) {
        var existingCount = result[getProp(obj)];
        result[getProp(obj)] = existingCount === undefined ? 1 : existingCount + 1;
        return result;
    }, {});
}
/**
 * Filter out falsy keys from an object. Falsy keys are keys with values of false, null, undefined, 0, or empty string.
 * @param obj The object to filter
 * @returns A new object with falsy keys removed
 */
export function filterFalsyKeys(obj) {
    return Object.fromEntries(Object.entries(obj).filter(function (_a) {
        var v = _a[1];
        return v;
    }));
}
export function count2DDictionaryValues(dictionary) {
    return Object.entries(dictionary).reduce(function (output, _a) {
        var _b;
        var key = _a[0], innerDict = _a[1];
        var innerDictOutput = Object.entries(innerDict).reduce(function (innerOutput, _a) {
            var _b;
            var key2 = _a[0], vals = _a[1];
            return __assign(__assign({}, innerOutput), (_b = {}, _b[key2] = vals.length, _b));
        }, {});
        return __assign(__assign({}, output), (_b = {}, _b[key] = innerDictOutput, _b));
    }, {});
}
export function count3DDictionaryValues(dictionary, innerPropName) {
    return Object.entries(dictionary).reduce(function (output, _a) {
        var _b;
        var key = _a[0], innerDict = _a[1];
        var innerDictOutput = Object.entries(innerDict).reduce(function (innerOutput, _a) {
            var _b;
            var key2 = _a[0], vals = _a[1];
            return __assign(__assign({}, innerOutput), (_b = {}, _b[key2] = vals[innerPropName].length, _b));
        }, {});
        return __assign(__assign({}, output), (_b = {}, _b[key] = innerDictOutput, _b));
    }, {});
}
//# sourceMappingURL=ObjectUtils.js.map