"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
const Log_1 = require("../../core/Log");
const ste_events_1 = require("ste-events");
const DocumentedClass_1 = require("./DocumentedClass");
const Project_1 = require("../../app/Project");
const DocumentedScriptEnum_1 = require("./DocumentedScriptEnum");
class DocumentedModule {
    _file;
    _id;
    _name;
    _version;
    _isLoaded = false;
    _isUnassociatedDocsLoaded = false;
    _docFolder;
    _docClassesAndInterfaces = {};
    _docEnums = {};
    _associatedInfoJsonFiles = {};
    _unassociatedInfoJsonFiles = {};
    moduleDefinition;
    _onLoaded = new ste_events_1.EventDispatcher();
    get isLoaded() {
        return this._isLoaded;
    }
    get unassociatedInfoJsonFiles() {
        return this._unassociatedInfoJsonFiles;
    }
    get isUnassociatedDocsLoaded() {
        return this._isUnassociatedDocsLoaded;
    }
    get docFolder() {
        return this._docFolder;
    }
    get classes() {
        return this._docClassesAndInterfaces;
    }
    get enums() {
        return this._docEnums;
    }
    get file() {
        return this._file;
    }
    set file(newFile) {
        this._file = newFile;
    }
    get onLoaded() {
        return this._onLoaded.asEvent();
    }
    get uuid() {
        if (!this.moduleDefinition) {
            return undefined;
        }
        return this.moduleDefinition.uuid;
    }
    get moduleType() {
        if (!this.moduleDefinition) {
            return undefined;
        }
        return this.moduleDefinition.module_type;
    }
    get name() {
        if (this.moduleDefinition) {
            return this.moduleDefinition.name;
        }
        return this._name;
    }
    get version() {
        if (this.moduleDefinition) {
            return this.moduleDefinition.version;
        }
        return this._version;
    }
    get id() {
        return this._id;
    }
    set id(newId) {
        this._id = newId;
        if (newId) {
            const underscore = newId.lastIndexOf("_");
            if (underscore >= 0 && underscore < newId.length - 2) {
                this._name = newId.substring(0, underscore);
                this._version = newId.substring(underscore + 1);
            }
            else {
                this._name = newId;
                this._version = "";
            }
        }
    }
    constructor(docFolder) {
        this._docFolder = docFolder;
    }
    associateParentClasses() {
        for (const docClassName in this.classes) {
            const docClass = this.classes[docClassName];
            docClass.parentClasses = [];
            const bts = docClass.docClass.base_types;
            if (bts) {
                for (const bt of bts) {
                    const parentC = this.classes[bt.name];
                    if (parentC) {
                        docClass.parentClasses.push(parentC);
                    }
                }
            }
        }
    }
    async loadUnassociatedDocumentation(force) {
        if (this._isUnassociatedDocsLoaded && !force) {
            return;
        }
        this._associatedInfoJsonFiles = {};
        this._unassociatedInfoJsonFiles = {};
        for (const dcName in this._docClassesAndInterfaces) {
            const dc = this._docClassesAndInterfaces[dcName];
            for (const memberName in dc.infoJsonFiles) {
                const infoJson = dc.infoJsonFiles[memberName];
                if (infoJson) {
                    this._associatedInfoJsonFiles[infoJson.storageRelativePath] = infoJson;
                }
            }
        }
        for (const dcName in this._docEnums) {
            const denum = this._docEnums[dcName];
            for (const memberName in denum.infoJsonFiles) {
                const infoJson = denum.infoJsonFiles[memberName];
                if (infoJson) {
                    this._associatedInfoJsonFiles[infoJson.storageRelativePath] = infoJson;
                }
            }
        }
        await this.loadUnassociatedDocumentationFolder(this.docFolder);
        this._isUnassociatedDocsLoaded = true;
    }
    async loadUnassociatedDocumentationFolder(folder) {
        if (!folder.isLoaded) {
            await folder.load();
        }
        for (const fileName in folder.files) {
            const file = folder.files[fileName];
            if (file && file.name === "info.json" && this._associatedInfoJsonFiles[file.storageRelativePath] === undefined) {
                this._unassociatedInfoJsonFiles[file.storageRelativePath] = file;
            }
        }
        for (const folderName in folder.folders) {
            const childFolder = folder.folders[folderName];
            if (childFolder) {
                await this.loadUnassociatedDocumentationFolder(childFolder);
            }
        }
    }
    static async ensureOnFile(file, docFolder, loadHandler) {
        if (file.manager === undefined) {
            const dt = new DocumentedModule(docFolder);
            dt.file = file;
            file.manager = dt;
        }
        if (file.manager !== undefined && file.manager instanceof DocumentedModule) {
            const dt = file.manager;
            if (!dt.isLoaded) {
                if (loadHandler) {
                    dt.onLoaded.subscribe(loadHandler);
                }
                await dt.load();
            }
        }
    }
    ensureDocFolder(docsFolder) {
        if (!this.name) {
            return;
        }
        let folderName = this.name;
        folderName = folderName.toLowerCase();
        if (Project_1.remappedMinecraftScriptModules[folderName]) {
            folderName = Project_1.remappedMinecraftScriptModules[folderName];
        }
        const folders = folderName.split("/");
        let curFolder = docsFolder;
        for (let i = 0; i < folders.length; i++) {
            curFolder = curFolder.ensureFolder(folders[i]);
        }
        return curFolder;
    }
    async persist() {
        if (this._file === undefined) {
            return;
        }
        for (const docClassName in this._docClassesAndInterfaces) {
            const docClass = this._docClassesAndInterfaces[docClassName];
            await docClass.persist();
        }
        for (const docEnumName in this._docEnums) {
            const docEnum = this._docEnums[docEnumName];
            await docEnum.persist();
        }
    }
    async load() {
        if (this._file === undefined || this._isLoaded) {
            return;
        }
        if (!this._file.isContentLoaded) {
            await this._file.loadContent();
        }
        if (this._file.content === null || this._file.content instanceof Uint8Array) {
            return;
        }
        this.id = this._file.name;
        try {
            const data = JSON.parse(this._file.content);
            this.moduleDefinition = data;
        }
        catch (e) {
            Log_1.default.fail("Could not parse documented module JSON " + e);
        }
        this._docClassesAndInterfaces = {};
        if (this.moduleDefinition && this.moduleDefinition.classes) {
            for (const docClass of this.moduleDefinition?.classes) {
                this._docClassesAndInterfaces[docClass.name] = new DocumentedClass_1.default(this, docClass);
            }
            for (const docClass of this.moduleDefinition?.interfaces) {
                const dc = new DocumentedClass_1.default(this, docClass);
                dc.isInterface = true;
                this._docClassesAndInterfaces[docClass.name] = dc;
            }
        }
        if (this.moduleDefinition && this.moduleDefinition.errors) {
            for (const docError of this.moduleDefinition.errors) {
                this._docClassesAndInterfaces[docError.name] = new DocumentedClass_1.default(this, docError);
            }
        }
        this._docEnums = {};
        if (this.moduleDefinition && this.moduleDefinition.enums) {
            for (const docEnum of this.moduleDefinition.enums) {
                this._docEnums[docEnum.name] = new DocumentedScriptEnum_1.default(this, docEnum);
            }
        }
        this._isLoaded = true;
    }
}
exports.default = DocumentedModule;

//# sourceMappingURL=../../maps/minecraft/docs/DocumentedModule.js.map
