
import { __decorate, __param } from '../../../../../../external/tslib/tslib.es6.js';
import { localize } from '../../../nls.js';
import { ExtensionsRegistry } from '../../services/extensions/common/extensionsRegistry.js';
import { joinPath, isEqualOrParent } from '../../../base/common/resources.js';
import { isString } from '../../../base/common/types.js';
import { Disposable } from '../../../base/common/lifecycle.js';
import { Extensions } from '../../services/extensionManagement/common/extensionFeatures.js';
import { Registry } from '../../../platform/registry/common/platform.js';
import { SyncDescriptor } from '../../../platform/instantiation/common/descriptors.js';
import { MarkdownString } from '../../../base/common/htmlContent.js';
import { registerWorkbenchContribution2, WorkbenchPhase } from '../../common/contributions.js';
import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js';

const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint({
    extensionPoint: 'jsonValidation',
    defaultExtensionKind: ['workspace', 'web'],
    jsonSchema: {
        description: ( localize(2556, 'Contributes json schema configuration.')),
        type: 'array',
        defaultSnippets: [{ body: [{ fileMatch: '${1:file.json}', url: '${2:url}' }] }],
        items: {
            type: 'object',
            defaultSnippets: [{ body: { fileMatch: '${1:file.json}', url: '${2:url}' } }],
            properties: {
                fileMatch: {
                    type: ['string', 'array'],
                    description: ( localize(
                        2557,
                        'The file pattern (or an array of patterns) to match, for example "package.json" or "*.launch". Exclusion patterns start with \'!\''
                    )),
                    items: {
                        type: ['string']
                    }
                },
                url: {
                    description: ( localize(
                        2558,
                        'A schema URL (\'http:\', \'https:\') or relative path to the extension folder (\'./\').'
                    )),
                    type: 'string'
                }
            }
        }
    }
});
class JSONValidationExtensionPoint {
    constructor() {
        configurationExtPoint.setHandler((extensions) => {
            for (const extension of extensions) {
                const extensionValue = extension.value;
                const collector = extension.collector;
                const extensionLocation = extension.description.extensionLocation;
                if (!extensionValue || !Array.isArray(extensionValue)) {
                    collector.error(( localize(2559, "'configuration.jsonValidation' must be a array")));
                    return;
                }
                extensionValue.forEach(extension => {
                    if (!isString(extension.fileMatch) && !(Array.isArray(extension.fileMatch) && extension.fileMatch.every(isString))) {
                        collector.error(( localize(
                            2560,
                            "'configuration.jsonValidation.fileMatch' must be defined as a string or an array of strings."
                        )));
                        return;
                    }
                    const uri = extension.url;
                    if (!isString(uri)) {
                        collector.error(( localize(2561, "'configuration.jsonValidation.url' must be a URL or relative path")));
                        return;
                    }
                    if (uri.startsWith('./')) {
                        try {
                            const colorThemeLocation = joinPath(extensionLocation, uri);
                            if (!isEqualOrParent(colorThemeLocation, extensionLocation)) {
                                collector.warn(( localize(
                                    2562,
                                    "Expected `contributes.{0}.url` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.",
                                    configurationExtPoint.name,
                                    (colorThemeLocation.toString()),
                                    extensionLocation.path
                                )));
                            }
                        }
                        catch (e) {
                            collector.error(( localize(
                                2563,
                                "'configuration.jsonValidation.url' is an invalid relative URL: {0}",
                                e.message
                            )));
                        }
                    }
                    else if (!/^[^:/?#]+:\/\//.test(uri)) {
                        collector.error(( localize(
                            2564,
                            "'configuration.jsonValidation.url' must be an absolute URL or start with './'  to reference schemas located in the extension."
                        )));
                        return;
                    }
                });
            }
        });
    }
}
class JSONValidationDataRenderer extends Disposable {
    constructor() {
        super(...arguments);
        this.type = 'table';
    }
    shouldRender(manifest) {
        return !!manifest.contributes?.jsonValidation;
    }
    render(manifest) {
        const contrib = manifest.contributes?.jsonValidation || [];
        if (!contrib.length) {
            return { data: { headers: [], rows: [] }, dispose: () => { } };
        }
        const headers = [
            ( localize(2565, "File Match")),
            ( localize(2566, "Schema")),
        ];
        const rows = ( contrib.map(v => {
            return [
                ( new MarkdownString()).appendMarkdown(`\`${Array.isArray(v.fileMatch) ? v.fileMatch.join(', ') : v.fileMatch}\``),
                v.url,
            ];
        }));
        return {
            data: {
                headers,
                rows
            },
            dispose: () => { }
        };
    }
}
( Registry.as(Extensions.ExtensionFeaturesRegistry)).registerExtensionFeature({
    id: 'jsonValidation',
    label: ( localize(2567, "JSON Validation")),
    access: {
        canToggle: false
    },
    renderer: ( new SyncDescriptor(JSONValidationDataRenderer)),
});
let JSONValidationExtensionPointWorkbenchContribution = class JSONValidationExtensionPointWorkbenchContribution {
    static { this.ID = 'workbench.contrib.jsonValidationExtensionPoint'; }
    constructor(instantiationService) {
        this.instantiationService = instantiationService;
        this.instantiationService.createInstance(JSONValidationExtensionPoint);
    }
};
JSONValidationExtensionPointWorkbenchContribution = ( __decorate([
    ( __param(0, IInstantiationService))
], JSONValidationExtensionPointWorkbenchContribution));
registerWorkbenchContribution2(JSONValidationExtensionPointWorkbenchContribution.ID, JSONValidationExtensionPointWorkbenchContribution, WorkbenchPhase.BlockStartup);

export { JSONValidationExtensionPoint };
