"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PullDiagnosticsManager = exports.PushDiagnosticsManager = void 0;
const vscode_languageserver_1 = require("vscode-languageserver");
const utils_1 = require("../utils");
class PushDiagnosticsManager {
    constructor(sendDiagnostics, docManager, getDiagnostics) {
        this.sendDiagnostics = sendDiagnostics;
        this.docManager = docManager;
        this.getDiagnostics = getDiagnostics;
        this.pendingUpdates = new Set();
        this.cancellationTokens = new Map();
        this.debouncedUpdateAll = (0, utils_1.debounceThrottle)(() => this.updateAll(), 1000);
        this.scheduleBatchUpdate = (0, utils_1.debounceThrottle)(() => {
            this.pendingUpdates.forEach((doc) => {
                this.update(doc);
            });
            this.pendingUpdates.clear();
        }, 500);
    }
    updateAll() {
        this.docManager.getAllOpenedByClient().forEach((doc) => {
            this.update(doc[1]);
        });
        this.pendingUpdates.clear();
    }
    scheduleUpdateAll() {
        this.cancellationTokens.forEach((token) => token.cancel());
        this.cancellationTokens.clear();
        this.pendingUpdates.clear();
        this.debouncedUpdateAll();
    }
    async update(document) {
        const uri = document.getURL();
        this.cancelStarted(uri);
        const tokenSource = new vscode_languageserver_1.CancellationTokenSource();
        this.cancellationTokens.set(uri, tokenSource);
        const diagnostics = await this.getDiagnostics({ uri: document.getURL() }, tokenSource.token);
        this.sendDiagnostics({
            uri: document.getURL(),
            diagnostics
        });
        tokenSource.dispose();
        if (this.cancellationTokens.get(uri) === tokenSource) {
            this.cancellationTokens.delete(uri);
        }
    }
    cancelStarted(uri) {
        const started = this.cancellationTokens.get(uri);
        if (started) {
            started.cancel();
        }
    }
    removeDiagnostics(document) {
        this.pendingUpdates.delete(document);
        this.sendDiagnostics({
            uri: document.getURL(),
            diagnostics: []
        });
    }
    scheduleUpdate(document) {
        if (!this.docManager.isOpenedInClient(document.getURL())) {
            return;
        }
        this.cancelStarted(document.getURL());
        this.pendingUpdates.add(document);
        this.scheduleBatchUpdate();
    }
}
exports.PushDiagnosticsManager = PushDiagnosticsManager;
class PullDiagnosticsManager {
    constructor(sendDiagnostics, sendRefreshDiagnostics) {
        this.sendDiagnostics = sendDiagnostics;
        this.sendRefreshDiagnostics = sendRefreshDiagnostics;
        this.refreshTimeout = null;
    }
    scheduleUpdate() {
        // No-op, diagnostics are pulled by the client.
    }
    scheduleUpdateAll() {
        if (this.refreshTimeout) {
            clearTimeout(this.refreshTimeout);
        }
        this.refreshTimeout = setTimeout(() => {
            this.sendRefreshDiagnostics();
            this.refreshTimeout = null;
        }, 500);
    }
    removeDiagnostics(document) {
        this.sendDiagnostics({
            uri: document.getURL(),
            diagnostics: []
        });
    }
    cancelStarted() {
        // No-op, diagnostics are pulled by the client.
    }
}
exports.PullDiagnosticsManager = PullDiagnosticsManager;
//# sourceMappingURL=DiagnosticsManager.js.map