/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
export function combine(combiningInfo, currentValue, newValue, seq) {
    let _currentValue = currentValue;
    if (_currentValue === undefined) {
        _currentValue = combiningInfo.defaultValue;
    }
    // Fixed set of operations for now
    /* eslint-disable default-case */
    switch (combiningInfo.name) {
        case "incr":
            _currentValue += newValue;
            if (combiningInfo.minValue) {
                if (_currentValue < combiningInfo.minValue) {
                    _currentValue = combiningInfo.minValue;
                }
            }
            break;
        case "consensus":
            if (_currentValue === undefined) {
                const cv = {
                    value: newValue,
                    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                    seq: seq,
                };
                _currentValue = cv;
            }
            else {
                const cv = _currentValue;
                if (cv.seq === -1) {
                    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                    cv.seq = seq;
                }
            }
            break;
    }
    /* eslint-enable default-case */
    // eslint-disable-next-line @typescript-eslint/no-unsafe-return
    return _currentValue;
}
export function matchProperties(a, b) {
    if (a) {
        if (!b) {
            return false;
        }
        else {
            // For now, straightforward; later use hashing
            // eslint-disable-next-line no-restricted-syntax
            for (const key in a) {
                if (b[key] === undefined) {
                    return false;
                }
                else if (typeof b[key] === "object") {
                    if (!matchProperties(a[key], b[key])) {
                        return false;
                    }
                }
                else if (b[key] !== a[key]) {
                    return false;
                }
            }
            // eslint-disable-next-line no-restricted-syntax
            for (const key in b) {
                if (a[key] === undefined) {
                    return false;
                }
            }
        }
    }
    else {
        if (b) {
            return false;
        }
    }
    return true;
}
export function extend(base, extension, combiningOp, seq) {
    if (extension !== undefined) {
        if ((typeof extension !== "object")) {
            console.log(`oh my ${extension}`);
        }
        // eslint-disable-next-line guard-for-in, no-restricted-syntax
        for (const key in extension) {
            const v = extension[key];
            if (v === null) {
                // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
                delete base[key];
            }
            else {
                if (combiningOp && (combiningOp.name !== "rewrite")) {
                    base[key] = combine(combiningOp, base[key], v, seq);
                }
                else {
                    base[key] = v;
                }
            }
        }
    }
    return base;
}
export function clone(extension) {
    if (extension === undefined) {
        return undefined;
    }
    const cloneMap = createMap();
    // eslint-disable-next-line guard-for-in, no-restricted-syntax
    for (const key in extension) {
        const v = extension[key];
        if (v !== null) {
            cloneMap[key] = v;
        }
    }
    return cloneMap;
}
export function addProperties(oldProps, newProps, op, seq) {
    let _oldProps = oldProps;
    if ((!_oldProps) || (op && (op.name === "rewrite"))) {
        _oldProps = createMap();
    }
    extend(_oldProps, newProps, op, seq);
    return _oldProps;
}
export function extendIfUndefined(base, extension) {
    if (extension !== undefined) {
        if ((typeof extension !== "object")) {
            console.log(`oh my ${extension}`);
        }
        // eslint-disable-next-line no-restricted-syntax
        for (const key in extension) {
            if (base[key] === undefined) {
                base[key] = extension[key];
            }
        }
    }
    return base;
}
// Create a MapLike with good performance.
export function createMap() {
    return Object.create(null);
}
//# sourceMappingURL=properties.js.map