"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DocumentManager = void 0;
const events_1 = require("events");
const utils_1 = require("../../utils");
const typescript_1 = __importDefault(require("typescript"));
const fileCollection_1 = require("./fileCollection");
/**
 * Manages svelte documents
 */
class DocumentManager {
    constructor(createDocument, options = {
        useCaseSensitiveFileNames: typescript_1.default.sys.useCaseSensitiveFileNames
    }) {
        this.createDocument = createDocument;
        this.emitter = new events_1.EventEmitter();
        this.documents = new fileCollection_1.FileMap(options.useCaseSensitiveFileNames);
        this.locked = new fileCollection_1.FileSet(options.useCaseSensitiveFileNames);
        this.deleteCandidates = new fileCollection_1.FileSet(options.useCaseSensitiveFileNames);
    }
    openClientDocument(textDocument) {
        return this.openDocument(textDocument, /**openedByClient */ true);
    }
    openDocument(textDocument, openedByClient) {
        textDocument = {
            ...textDocument,
            uri: (0, utils_1.normalizeUri)(textDocument.uri)
        };
        let document;
        if (this.documents.has(textDocument.uri)) {
            document = this.documents.get(textDocument.uri);
            // open state should only be updated when the document is closed
            document.openedByClient ||= openedByClient;
            document.setText(textDocument.text);
            this.notify('documentChange', document);
        }
        else {
            document = this.createDocument(textDocument);
            document.openedByClient = openedByClient;
            this.documents.set(textDocument.uri, document);
            this.notify('documentOpen', document);
        }
        return document;
    }
    lockDocument(uri) {
        this.locked.add((0, utils_1.normalizeUri)(uri));
    }
    markAsOpenedInClient(uri) {
        const document = this.documents.get((0, utils_1.normalizeUri)(uri));
        if (document) {
            document.openedByClient = true;
        }
    }
    getAllOpenedByClient() {
        return Array.from(this.documents.entries()).filter((doc) => doc[1].openedByClient);
    }
    isOpenedInClient(uri) {
        const document = this.documents.get((0, utils_1.normalizeUri)(uri));
        return !!document?.openedByClient;
    }
    releaseDocument(uri) {
        uri = (0, utils_1.normalizeUri)(uri);
        this.locked.delete(uri);
        const document = this.documents.get(uri);
        if (document) {
            document.openedByClient = false;
        }
        if (this.deleteCandidates.has(uri)) {
            this.deleteCandidates.delete(uri);
            this.closeDocument(uri);
        }
    }
    closeDocument(uri) {
        uri = (0, utils_1.normalizeUri)(uri);
        const document = this.documents.get(uri);
        if (!document) {
            throw new Error('Cannot call methods on an unopened document');
        }
        this.notify('documentClose', document);
        // Some plugin may prevent a document from actually being closed.
        if (!this.locked.has(uri)) {
            this.documents.delete(uri);
        }
        else {
            this.deleteCandidates.add(uri);
        }
        document.openedByClient = false;
    }
    updateDocument(textDocument, changes) {
        const document = this.documents.get((0, utils_1.normalizeUri)(textDocument.uri));
        if (!document) {
            throw new Error('Cannot call methods on an unopened document');
        }
        document.update(changes);
        this.notify('documentChange', document);
    }
    on(name, listener) {
        this.emitter.on(name, listener);
    }
    get(uri) {
        return this.documents.get((0, utils_1.normalizeUri)(uri));
    }
    notify(name, document) {
        this.emitter.emit(name, document);
    }
}
exports.DocumentManager = DocumentManager;
//# sourceMappingURL=DocumentManager.js.map