
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { localize } from '../../../../nls.js';
import { ExtensionsRegistry } from '../../extensions/common/extensionsRegistry.js';
import { Extensions } from '../../../../platform/theme/common/iconRegistry.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { ThemeIcon } from '../../../../base/common/themables.js';
import { joinPath, isEqualOrParent } from '../../../../base/common/resources.js';
import { extname, posix } from '../../../../base/common/path.js';
import { registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';

const iconRegistry = ( Registry.as(Extensions.IconContribution));
const iconReferenceSchema = iconRegistry.getIconReferenceSchema();
const iconIdPattern = `^${ThemeIcon.iconNameSegment}(-${ThemeIcon.iconNameSegment})+$`;
const iconConfigurationExtPoint = ExtensionsRegistry.registerExtensionPoint({
    extensionPoint: 'icons',
    jsonSchema: {
        description: ( localize(12702, 'Contributes extension defined themable icons')),
        type: 'object',
        propertyNames: {
            pattern: iconIdPattern,
            description: ( localize(12703, 'The identifier of the themable icon')),
            patternErrorMessage: ( localize(
                12704,
                'Identifiers can only contain letters, digits and minuses and need to consist of at least two segments in the form `component-iconname`.'
            )),
        },
        additionalProperties: {
            type: 'object',
            properties: {
                description: {
                    type: 'string',
                    description: ( localize(12705, 'The description of the themable icon')),
                },
                default: {
                    anyOf: [
                        iconReferenceSchema,
                        {
                            type: 'object',
                            properties: {
                                fontPath: {
                                    description: ( localize(12706, 'The path of the icon font that defines the icon.')),
                                    type: 'string'
                                },
                                fontCharacter: {
                                    description: ( localize(12707, 'The character for the icon in the icon font.')),
                                    type: 'string'
                                }
                            },
                            required: ['fontPath', 'fontCharacter'],
                            defaultSnippets: [{ body: { fontPath: '${1:myiconfont.woff}', fontCharacter: '${2:\\\\E001}' } }]
                        }
                    ],
                    description: ( localize(
                        12708,
                        'The default of the icon. Either a reference to an existing ThemeIcon or an icon in an icon font.'
                    )),
                }
            },
            required: ['description', 'default'],
            defaultSnippets: [{ body: { description: '${1:my icon}', default: { fontPath: '${2:myiconfont.woff}', fontCharacter: '${3:\\\\E001}' } } }]
        },
        defaultSnippets: [{ body: { '${1:my-icon-id}': { description: '${2:my icon}', default: { fontPath: '${3:myiconfont.woff}', fontCharacter: '${4:\\\\E001}' } } } }]
    }
});
class IconExtensionPoint {
    constructor() {
        iconConfigurationExtPoint.setHandler((extensions, delta) => {
            for (const extension of delta.added) {
                const extensionValue = extension.value;
                const collector = extension.collector;
                if (!extensionValue || typeof extensionValue !== 'object') {
                    collector.error(( localize(
                        12709,
                        "'configuration.icons' must be an object with the icon names as properties."
                    )));
                    return;
                }
                for (const id in extensionValue) {
                    if (!id.match(iconIdPattern)) {
                        collector.error(( localize(
                            12710,
                            "'configuration.icons' keys represent the icon id and can only contain letter, digits and minuses. They need to consist of at least two segments in the form `component-iconname`."
                        )));
                        return;
                    }
                    const iconContribution = extensionValue[id];
                    if (typeof iconContribution.description !== 'string' || iconContribution.description.length === 0) {
                        collector.error(( localize(
                            12711,
                            "'configuration.icons.description' must be defined and can not be empty"
                        )));
                        return;
                    }
                    const defaultIcon = iconContribution.default;
                    if (typeof defaultIcon === 'string') {
                        iconRegistry.registerIcon(id, { id: defaultIcon }, iconContribution.description);
                    }
                    else if (typeof defaultIcon === 'object' && typeof defaultIcon.fontPath === 'string' && typeof defaultIcon.fontCharacter === 'string') {
                        const fileExt = extname(defaultIcon.fontPath).substring(1);
                        const format = formatMap[fileExt];
                        if (!format) {
                            collector.warn(( localize(
                                12712,
                                "Expected `contributes.icons.default.fontPath` to have file extension 'woff', woff2' or 'ttf', is '{0}'.",
                                fileExt
                            )));
                            return;
                        }
                        const extensionLocation = extension.description.extensionLocation;
                        const iconFontLocation = joinPath(extensionLocation, defaultIcon.fontPath);
                        const fontId = getFontId(extension.description, defaultIcon.fontPath);
                        const definition = iconRegistry.registerIconFont(fontId, { src: [{ location: iconFontLocation, format }] });
                        if (!isEqualOrParent(iconFontLocation, extensionLocation)) {
                            collector.warn(( localize(
                                12713,
                                "Expected `contributes.icons.default.fontPath` ({0}) to be included inside extension's folder ({0}).",
                                iconFontLocation.path,
                                extensionLocation.path
                            )));
                            return;
                        }
                        iconRegistry.registerIcon(id, {
                            fontCharacter: defaultIcon.fontCharacter,
                            font: {
                                id: fontId,
                                definition
                            }
                        }, iconContribution.description);
                    }
                    else {
                        collector.error(( localize(
                            12714,
                            "'configuration.icons.default' must be either a reference to the id of an other theme icon (string) or a icon definition (object) with properties `fontPath` and `fontCharacter`."
                        )));
                    }
                }
            }
            for (const extension of delta.removed) {
                const extensionValue = extension.value;
                for (const id in extensionValue) {
                    iconRegistry.deregisterIcon(id);
                }
            }
        });
    }
}
const formatMap = {
    'ttf': 'truetype',
    'woff': 'woff',
    'woff2': 'woff2'
};
function getFontId(description, fontPath) {
    return posix.join(description.identifier.value, fontPath);
}
let ColorExtensionPointWorkbenchContribution = class ColorExtensionPointWorkbenchContribution {
    static { this.ID = 'workbench.contrib.iconExtensionPoint'; }
    constructor(instantiationService) {
        this.instantiationService = instantiationService;
        this.instantiationService.createInstance(IconExtensionPoint);
    }
};
ColorExtensionPointWorkbenchContribution = ( __decorate([
    ( __param(0, IInstantiationService))
], ColorExtensionPointWorkbenchContribution));
registerWorkbenchContribution2(ColorExtensionPointWorkbenchContribution.ID, ColorExtensionPointWorkbenchContribution, WorkbenchPhase.BlockStartup);

export { IconExtensionPoint };
