"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AdaptableHelper = void 0;
exports.addUuidsToInitialState = addUuidsToInitialState;
exports.getAccessLevelForObject = getAccessLevelForObject;
exports.addAdaptableObjectPrimitives = addAdaptableObjectPrimitives;
exports.removeAdaptableObjectPrimitivesInlineDeep = removeAdaptableObjectPrimitivesInlineDeep;
exports.removeAdaptableObjectPrimitivesInline = removeAdaptableObjectPrimitivesInline;
exports.removeAdaptableObjectPrimitives = removeAdaptableObjectPrimitives;
exports.isAdaptableObject = isAdaptableObject;
const tslib_1 = require("tslib");
const cloneDeepWith_1 = tslib_1.__importDefault(require("../utils/cloneDeepWith"));
const isPlainObject_1 = tslib_1.__importDefault(require("../utils/isPlainObject"));
const Uuid_1 = require("../../AdaptableState/Uuid");
const package_json_1 = tslib_1.__importDefault(require("../../../package.json"));
const GET_CURRENT_VERSION = () => {
    const globalObject = typeof globalThis !== 'undefined' ? globalThis : window;
    return ((typeof globalObject['GET_CURRENT_ADAPTABLE_VERSION'] === 'function'
        ? globalObject['GET_CURRENT_ADAPTABLE_VERSION']()
        : package_json_1.default.version) ?? package_json_1.default.version);
};
function addUuidsToInitialState(initialState) {
    const customizer = (value) => {
        // so whenever we clone a plain object,
        // we add a Uuid property
        // jw added 9/8/20: unless there is on there already
        if ((0, isPlainObject_1.default)(value) && value != initialState) {
            if (value.Uuid == null || value.Uuid == undefined) {
                value.Uuid = (0, Uuid_1.createUuid)();
            }
            if (value.AdaptableVersion == null) {
                value.AdaptableVersion = GET_CURRENT_VERSION();
            }
        }
    };
    return (0, cloneDeepWith_1.default)(initialState, customizer);
}
function getAccessLevelForObject(adaptableObject, moduleAccessLevel) {
    // we always return the Module Access Level unless the following condition is met:
    // the object prpoerty has been set and set to true and the Module entitlement is full
    if (moduleAccessLevel == 'Full' &&
        adaptableObject &&
        adaptableObject.IsReadOnly &&
        adaptableObject.IsReadOnly == true) {
        return 'ReadOnly';
    }
    return moduleAccessLevel;
}
function addAdaptableObjectPrimitives(adaptableObject) {
    if (!adaptableObject.Uuid) {
        adaptableObject.Uuid = (0, Uuid_1.createUuid)();
    }
    adaptableObject.Source = 'User';
    adaptableObject.AdaptableVersion = GET_CURRENT_VERSION();
    return adaptableObject;
}
function removeAdaptableObjectPrimitivesInlineDeep(target) {
    if (!target) {
        return target;
    }
    if (Array.isArray(target)) {
        target.forEach(removeAdaptableObjectPrimitivesInlineDeep);
        return target;
    }
    if (typeof target !== 'object') {
        return target;
    }
    delete target.Source;
    delete target.Uuid;
    delete target.AdaptableVersion;
    for (const key in target) {
        removeAdaptableObjectPrimitivesInlineDeep(target[key]);
    }
    return target;
}
function removeAdaptableObjectPrimitivesInline(target) {
    if (!target) {
        return target;
    }
    if (Array.isArray(target)) {
        target.forEach(removeAdaptableObjectPrimitivesInline);
        return target;
    }
    if (typeof target !== 'object') {
        return target;
    }
    delete target.Source;
    delete target.Uuid;
    delete target.AdaptableVersion;
    return target;
}
function removeAdaptableObjectPrimitives(adaptableObject) {
    const clonedObject = structuredClone(adaptableObject);
    const sanitiseObject = (object) => {
        for (const key in object) {
            if (key === 'Source' || key === 'Uuid' || key === 'AdaptableVersion') {
                delete object[key];
            }
            else if (Array.isArray(object[key])) {
                object[key].forEach((item) => sanitiseObject(item));
            }
            else if (typeof object[key] === 'object') {
                sanitiseObject(object[key]);
            }
        }
    };
    sanitiseObject(clonedObject);
    return clonedObject;
}
// pretty primitive type guard for AdaptableObject, but currently there is no better/safer way
function isAdaptableObject(object) {
    return object != undefined && typeof object['Uuid'] === 'string';
}
exports.AdaptableHelper = {
    addUuidsToInitialState: addUuidsToInitialState,
    getAccessLevelForObject,
    addAdaptableObjectPrimitives,
    removeAdaptableObjectPrimitives,
    removeAdaptableObjectPrimitivesInline,
    removeAdaptableObjectPrimitivesInlineDeep,
    isAdaptableObject,
};
exports.default = exports.AdaptableHelper;
