import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { Emitter } from '../../../../base/common/event.js';
import { parse } from '../../../../base/common/glob.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { isAbsolute, parse as parse$1 } from '../../../../base/common/path.js';
import { relativePath } from '../../../../base/common/resources.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.service.js';
import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.service.js';
import '../../../../platform/instantiation/common/instantiation.js';
var CustomEditorLabelService_1;
let CustomEditorLabelService = class CustomEditorLabelService extends Disposable {
    static { CustomEditorLabelService_1 = this; }
    static { this.SETTING_ID_PATTERNS = 'workbench.editor.customLabels.patterns'; }
    static { this.SETTING_ID_ENABLED = 'workbench.editor.customLabels.enabled'; }
    constructor(configurationService, workspaceContextService) {
        super();
        this.configurationService = configurationService;
        this.workspaceContextService = workspaceContextService;
        this._onDidChange = this._register(( new Emitter()));
        this.onDidChange = this._onDidChange.event;
        this.patterns = [];
        this.enabled = true;
        this._templateRegexValidation = /[a-zA-Z0-9]/;
        this._parsedTemplateExpression = /\$\{(dirname|filename|extname|dirname\((\d+)\))\}/g;
        this.storeEnablementState();
        this.storeCustomPatterns();
        this.registerListernes();
    }
    registerListernes() {
        this._register(this.configurationService.onDidChangeConfiguration(e => {
            if (e.affectsConfiguration(CustomEditorLabelService_1.SETTING_ID_ENABLED)) {
                const oldEnablement = this.enabled;
                this.storeEnablementState();
                if (oldEnablement !== this.enabled && this.patterns.length > 0) {
                    this._onDidChange.fire();
                }
            }
            else if (e.affectsConfiguration(CustomEditorLabelService_1.SETTING_ID_PATTERNS)) {
                this.storeCustomPatterns();
                this._onDidChange.fire();
            }
        }));
    }
    storeEnablementState() {
        this.enabled = this.configurationService.getValue(CustomEditorLabelService_1.SETTING_ID_ENABLED);
    }
    storeCustomPatterns() {
        this.patterns = [];
        const customLabelPatterns = this.configurationService.getValue(CustomEditorLabelService_1.SETTING_ID_PATTERNS);
        for (const pattern in customLabelPatterns) {
            const template = customLabelPatterns[pattern];
            if (!this._templateRegexValidation.test(template)) {
                continue;
            }
            const isAbsolutePath = isAbsolute(pattern);
            const parsedPattern = parse(pattern);
            this.patterns.push({ pattern, template, isAbsolutePath, parsedPattern });
        }
        this.patterns.sort((a, b) => this.patternWeight(b.pattern) - this.patternWeight(a.pattern));
    }
    patternWeight(pattern) {
        let weight = 0;
        for (const fragment of pattern.split('/')) {
            if (fragment === '**') {
                weight += 1;
            }
            else if (fragment === '*') {
                weight += 10;
            }
            else if (fragment.includes('*') || fragment.includes('?')) {
                weight += 50;
            }
            else if (fragment !== '') {
                weight += 100;
            }
        }
        return weight;
    }
    getName(resource) {
        if (!this.enabled) {
            return undefined;
        }
        return this.applyPatterns(resource);
    }
    applyPatterns(resource) {
        if (this.patterns.length === 0) {
            return undefined;
        }
        const root = this.workspaceContextService.getWorkspaceFolder(resource);
        let relativePath$1;
        for (const pattern of this.patterns) {
            let relevantPath;
            if (root && !pattern.isAbsolutePath) {
                relevantPath = relativePath$1 = relativePath$1 ?? relativePath(root.uri, resource) ?? resource.path;
            }
            else {
                relevantPath = resource.path;
            }
            if (pattern.parsedPattern(relevantPath)) {
                return this.applyTempate(pattern.template, resource);
            }
        }
        return undefined;
    }
    applyTempate(template, resource) {
        let parsedPath;
        return template.replace(this._parsedTemplateExpression, (match, variable, arg) => {
            parsedPath = parsedPath ?? parse$1(resource.path);
            switch (variable) {
                case 'filename':
                    return parsedPath.name;
                case 'extname':
                    return parsedPath.ext.slice(1);
                default: {
                    const n = variable === 'dirname' ? 0 : parseInt(arg);
                    const nthDir = this.getNthDirname(parsedPath, n);
                    if (nthDir) {
                        return nthDir;
                    }
                }
            }
            return match;
        });
    }
    getNthDirname(path, n) {
        const pathFragments = path.dir.split('/');
        const length = pathFragments.length;
        const nth = length - 1 - n;
        if (nth < 0) {
            return undefined;
        }
        const nthDir = pathFragments[nth];
        if (nthDir === undefined || nthDir === '') {
            return undefined;
        }
        return nthDir;
    }
};
CustomEditorLabelService = CustomEditorLabelService_1 = ( __decorate([
    ( __param(0, IConfigurationService)),
    ( __param(1, IWorkspaceContextService))
], CustomEditorLabelService));
export { CustomEditorLabelService };
