"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FallbackWatcher = void 0;
const chokidar_1 = require("chokidar");
const lodash_1 = require("lodash");
const path_1 = require("path");
const vscode_languageserver_1 = require("vscode-languageserver");
const utils_1 = require("../utils");
const url_1 = require("url");
const DELAY = 50;
class FallbackWatcher {
    constructor(watchExtensions, workspacePaths) {
        this.callbacks = [];
        this.undeliveredFileEvents = [];
        this.scheduleTrigger = (0, lodash_1.debounce)(() => {
            const para = {
                changes: this.undeliveredFileEvents
            };
            this.undeliveredFileEvents = [];
            this.callbacks.forEach((callback) => callback(para));
        }, DELAY);
        const gitOrNodeModules = /\.git|node_modules/;
        const ignoredExtensions = (fileName, stats) => {
            return (stats?.isFile() === true && !watchExtensions.some((ext) => fileName.endsWith(ext)));
        };
        this.watcher = (0, chokidar_1.watch)(workspacePaths, {
            ignored: [gitOrNodeModules, ignoredExtensions],
            // typescript would scan the project files on init.
            // We only need to know what got updated.
            ignoreInitial: true,
            ignorePermissionErrors: true
        });
        this.watcher
            .on('add', (path) => this.onFSEvent(path, vscode_languageserver_1.FileChangeType.Created))
            .on('unlink', (path) => this.onFSEvent(path, vscode_languageserver_1.FileChangeType.Deleted))
            .on('change', (path) => this.onFSEvent(path, vscode_languageserver_1.FileChangeType.Changed));
    }
    convert(path, type) {
        return {
            type,
            uri: (0, utils_1.pathToUrl)(path)
        };
    }
    onFSEvent(path, type) {
        const fileEvent = this.convert(path, type);
        this.undeliveredFileEvents.push(fileEvent);
        this.scheduleTrigger();
    }
    onDidChangeWatchedFiles(callback) {
        this.callbacks.push(callback);
    }
    watchDirectory(patterns) {
        for (const pattern of patterns) {
            const basePath = (0, url_1.fileURLToPath)(typeof pattern.baseUri === 'string' ? pattern.baseUri : pattern.baseUri.uri);
            if (!basePath) {
                continue;
            }
            this.watcher.add((0, path_1.join)(basePath, pattern.pattern));
        }
    }
    dispose() {
        this.watcher.close();
    }
}
exports.FallbackWatcher = FallbackWatcher;
//# sourceMappingURL=FallbackWatcher.js.map