
import { assertNever } from '../../../base/common/assert.js';
import { URI } from '../../../base/common/uri.js';

function isConfigurationOverrides(thing) {
    return thing
        && typeof thing === 'object'
        && (!thing.overrideIdentifier || typeof thing.overrideIdentifier === 'string')
        && (!thing.resource || thing.resource instanceof URI);
}
function isConfigurationUpdateOverrides(thing) {
    return thing
        && typeof thing === 'object'
        && (!thing.overrideIdentifiers || Array.isArray(thing.overrideIdentifiers))
        && !thing.overrideIdentifier
        && (!thing.resource || thing.resource instanceof URI);
}
var ConfigurationTarget;
(function (ConfigurationTarget) {
    ConfigurationTarget[ConfigurationTarget["APPLICATION"] = 1] = "APPLICATION";
    ConfigurationTarget[ConfigurationTarget["USER"] = 2] = "USER";
    ConfigurationTarget[ConfigurationTarget["USER_LOCAL"] = 3] = "USER_LOCAL";
    ConfigurationTarget[ConfigurationTarget["USER_REMOTE"] = 4] = "USER_REMOTE";
    ConfigurationTarget[ConfigurationTarget["WORKSPACE"] = 5] = "WORKSPACE";
    ConfigurationTarget[ConfigurationTarget["WORKSPACE_FOLDER"] = 6] = "WORKSPACE_FOLDER";
    ConfigurationTarget[ConfigurationTarget["DEFAULT"] = 7] = "DEFAULT";
    ConfigurationTarget[ConfigurationTarget["MEMORY"] = 8] = "MEMORY";
})(ConfigurationTarget || (ConfigurationTarget = {}));
function ConfigurationTargetToString(configurationTarget) {
    switch (configurationTarget) {
        case ConfigurationTarget.APPLICATION: return 'APPLICATION';
        case ConfigurationTarget.USER: return 'USER';
        case ConfigurationTarget.USER_LOCAL: return 'USER_LOCAL';
        case ConfigurationTarget.USER_REMOTE: return 'USER_REMOTE';
        case ConfigurationTarget.WORKSPACE: return 'WORKSPACE';
        case ConfigurationTarget.WORKSPACE_FOLDER: return 'WORKSPACE_FOLDER';
        case ConfigurationTarget.DEFAULT: return 'DEFAULT';
        case ConfigurationTarget.MEMORY: return 'MEMORY';
    }
}
function getConfigValueInTarget(configValue, scope) {
    switch (scope) {
        case ConfigurationTarget.APPLICATION:
            return configValue.applicationValue;
        case ConfigurationTarget.USER:
            return configValue.userValue;
        case ConfigurationTarget.USER_LOCAL:
            return configValue.userLocalValue;
        case ConfigurationTarget.USER_REMOTE:
            return configValue.userRemoteValue;
        case ConfigurationTarget.WORKSPACE:
            return configValue.workspaceValue;
        case ConfigurationTarget.WORKSPACE_FOLDER:
            return configValue.workspaceFolderValue;
        case ConfigurationTarget.DEFAULT:
            return configValue.defaultValue;
        case ConfigurationTarget.MEMORY:
            return configValue.memoryValue;
        default:
            assertNever();
    }
}
function isConfigured(configValue) {
    return configValue.applicationValue !== undefined ||
        configValue.userValue !== undefined ||
        configValue.userLocalValue !== undefined ||
        configValue.userRemoteValue !== undefined ||
        configValue.workspaceValue !== undefined ||
        configValue.workspaceFolderValue !== undefined;
}
function toValuesTree(properties, conflictReporter) {
    const root = Object.create(null);
    for (const key in properties) {
        addToValueTree(root, key, properties[key], conflictReporter);
    }
    return root;
}
function addToValueTree(settingsTreeRoot, key, value, conflictReporter) {
    const segments = key.split('.');
    const last = segments.pop();
    let curr = settingsTreeRoot;
    for (let i = 0; i < segments.length; i++) {
        const s = segments[i];
        let obj = curr[s];
        switch (typeof obj) {
            case 'undefined':
                obj = curr[s] = Object.create(null);
                break;
            case 'object':
                if (obj === null) {
                    conflictReporter(`Ignoring ${key} as ${segments.slice(0, i + 1).join('.')} is null`);
                    return;
                }
                break;
            default:
                conflictReporter(`Ignoring ${key} as ${segments.slice(0, i + 1).join('.')} is ${JSON.stringify(obj)}`);
                return;
        }
        curr = obj;
    }
    if (typeof curr === 'object' && curr !== null) {
        try {
            curr[last] = value;
        }
        catch (e) {
            conflictReporter(`Ignoring ${key} as ${segments.join('.')} is ${JSON.stringify(curr)}`);
        }
    }
    else {
        conflictReporter(`Ignoring ${key} as ${segments.join('.')} is ${JSON.stringify(curr)}`);
    }
}
function removeFromValueTree(valueTree, key) {
    const segments = key.split('.');
    doRemoveFromValueTree(valueTree, segments);
}
function doRemoveFromValueTree(valueTree, segments) {
    if (!valueTree) {
        return;
    }
    const first = segments.shift();
    if (segments.length === 0) {
        delete valueTree[first];
        return;
    }
    if (( Object.keys(valueTree)).indexOf(first) !== -1) {
        const value = valueTree[first];
        if (typeof value === 'object' && !Array.isArray(value)) {
            doRemoveFromValueTree(value, segments);
            if (( Object.keys(value)).length === 0) {
                delete valueTree[first];
            }
        }
    }
}
function getConfigurationValue(config, settingPath, defaultValue) {
    function accessSetting(config, path) {
        let current = config;
        for (const component of path) {
            if (typeof current !== 'object' || current === null) {
                return undefined;
            }
            current = current[component];
        }
        return current;
    }
    const path = settingPath.split('.');
    const result = accessSetting(config, path);
    return typeof result === 'undefined' ? defaultValue : result;
}
function getLanguageTagSettingPlainKey(settingKey) {
    return settingKey.replace(/[\[\]]/g, '');
}

export { ConfigurationTarget, ConfigurationTargetToString, addToValueTree, getConfigValueInTarget, getConfigurationValue, getLanguageTagSettingPlainKey, isConfigurationOverrides, isConfigurationUpdateOverrides, isConfigured, removeFromValueTree, toValuesTree };
