/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
import { TernarySearchTree } from '../../../base/common/map.js';
import { createDecorator } from '../../instantiation/common/instantiation.js';
//#region file service & providers
export const IFileService = createDecorator('fileService');
export class FileChangesEvent {
    constructor(changes, ignorePathCasing) {
        this.added = undefined;
        this.updated = undefined;
        this.deleted = undefined;
        const entriesByType = new Map();
        for (const change of changes) {
            const array = entriesByType.get(change.type);
            if (array) {
                array.push([change.resource, change]);
            }
            else {
                entriesByType.set(change.type, [[change.resource, change]]);
            }
        }
        for (const [key, value] of entriesByType) {
            switch (key) {
                case 1 /* ADDED */:
                    this.added = TernarySearchTree.forUris(() => ignorePathCasing);
                    this.added.fill(value);
                    break;
                case 0 /* UPDATED */:
                    this.updated = TernarySearchTree.forUris(() => ignorePathCasing);
                    this.updated.fill(value);
                    break;
                case 2 /* DELETED */:
                    this.deleted = TernarySearchTree.forUris(() => ignorePathCasing);
                    this.deleted.fill(value);
                    break;
            }
        }
    }
    /**
     * Find out if the file change events match the provided resource.
     *
     * Note: when passing `FileChangeType.DELETED`, we consider a match
     * also when the parent of the resource got deleted.
     */
    contains(resource, ...types) {
        return this.doContains(resource, { includeChildren: false }, ...types);
    }
    doContains(resource, options, ...types) {
        var _a, _b, _c, _d, _e, _f;
        if (!resource) {
            return false;
        }
        const hasTypesFilter = types.length > 0;
        // Added
        if (!hasTypesFilter || types.includes(1 /* ADDED */)) {
            if ((_a = this.added) === null || _a === void 0 ? void 0 : _a.get(resource)) {
                return true;
            }
            if (options.includeChildren && ((_b = this.added) === null || _b === void 0 ? void 0 : _b.findSuperstr(resource))) {
                return true;
            }
        }
        // Updated
        if (!hasTypesFilter || types.includes(0 /* UPDATED */)) {
            if ((_c = this.updated) === null || _c === void 0 ? void 0 : _c.get(resource)) {
                return true;
            }
            if (options.includeChildren && ((_d = this.updated) === null || _d === void 0 ? void 0 : _d.findSuperstr(resource))) {
                return true;
            }
        }
        // Deleted
        if (!hasTypesFilter || types.includes(2 /* DELETED */)) {
            if ((_e = this.deleted) === null || _e === void 0 ? void 0 : _e.findSubstr(resource) /* deleted also considers parent folders */) {
                return true;
            }
            if (options.includeChildren && ((_f = this.deleted) === null || _f === void 0 ? void 0 : _f.findSuperstr(resource))) {
                return true;
            }
        }
        return false;
    }
}
//#endregion
//#region Utilities
export var FileKind;
(function (FileKind) {
    FileKind[FileKind["FILE"] = 0] = "FILE";
    FileKind[FileKind["FOLDER"] = 1] = "FOLDER";
    FileKind[FileKind["ROOT_FOLDER"] = 2] = "ROOT_FOLDER";
})(FileKind || (FileKind = {}));
//#endregion
