"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MATERIAL_NAMES_TO_FIXUP = exports.STANDARD_NAME_TOKEN = void 0;
const Log_1 = require("../core/Log");
const Utilities_1 = require("../core/Utilities");
const BlockTypeDefinition_1 = require("../minecraft/BlockTypeDefinition");
const Database_1 = require("../minecraft/Database");
const MinecraftDefinitions_1 = require("../minecraft/MinecraftDefinitions");
const HttpStorage_1 = require("../storage/HttpStorage");
const CartoApp_1 = require("./CartoApp");
const IProjectItemData_1 = require("./IProjectItemData");
const ProjectItemUtilities_1 = require("./ProjectItemUtilities");
exports.STANDARD_NAME_TOKEN = "_name_";
exports.MATERIAL_NAMES_TO_FIXUP = [
    "cold",
    "warm",
    "body",
    "head",
    "legs",
    "eyes",
    "flower",
    "charging",
    "masked",
    "bioluminescent_layer",
    "armor",
    "charged",
    "ghost",
    "cape",
    "body_layer",
    "outer",
    "animated",
    "spectator",
    "overlay",
    "limbs",
    "breeze_eyes",
    "breeze_wind",
    "invisible",
];
class ProjectCreateManager {
    static async addEntityTypeFromGallery(project, entityTypeProject, entityTypeName, addMode, messageUpdater, dontOverwriteExistingFiles) {
        await ProjectCreateManager.copyGalleryPackFilesAndFixupIds(project, entityTypeProject, entityTypeName, messageUpdater, dontOverwriteExistingFiles);
        await project.inferProjectItemsFromFiles(true);
        const items = project.getItemsCopy();
        for (const item of items) {
            if (item.itemType === IProjectItemData_1.ProjectItemType.entityTypeBehavior) {
                let minecraftEntityType = (await MinecraftDefinitions_1.default.get(item));
                if (minecraftEntityType) {
                    const targetId = entityTypeName ? entityTypeName : entityTypeProject.id;
                    if (minecraftEntityType.id?.endsWith(targetId)) {
                        minecraftEntityType.runtimeIdentifier = entityTypeProject.targetRuntimeIdentifier
                            ? entityTypeProject.targetRuntimeIdentifier
                            : "minecraft:" + entityTypeProject.id;
                        minecraftEntityType.persist();
                    }
                }
            }
        }
        await project.save();
    }
    static getReplacedCreationData(project, galleryItem, newName) {
        if (galleryItem.creationData === undefined) {
            return undefined;
        }
        try {
            let creationDataStr = JSON.stringify(galleryItem.creationData);
            creationDataStr = this.replaceNamesInContent(creationDataStr, project, galleryItem, newName, []);
            return JSON.parse(creationDataStr);
        }
        catch (e) {
            return galleryItem.creationData;
        }
    }
    static getReplacedCreationDataInObject(project, creationObject, newName) {
        if (creationObject === undefined) {
            return undefined;
        }
        try {
            let creationDataStr = JSON.stringify(creationObject);
            creationDataStr = this.replaceNamesInContentFromReplacers(creationDataStr, project, [exports.STANDARD_NAME_TOKEN], newName, []);
            return JSON.parse(creationDataStr);
        }
        catch (e) {
            return creationObject;
        }
    }
    static async addBlockTypeFromGallery(project, blockTypeProject, blockTypeName) {
        blockTypeName = await ProjectCreateManager.copyGalleryPackFilesAndFixupIds(project, blockTypeProject, blockTypeName);
        await project.inferProjectItemsFromFiles(true);
        const blockTypeItem = ProjectItemUtilities_1.default.getItemByTypeAndName(project, blockTypeName, IProjectItemData_1.ProjectItemType.blockTypeBehavior);
        if (blockTypeItem) {
            if (!blockTypeItem.isContentLoaded) {
                await blockTypeItem.loadContent();
            }
            if (blockTypeItem.primaryFile) {
                const blockType = await BlockTypeDefinition_1.default.ensureOnFile(blockTypeItem.primaryFile);
                const creationData = this.getReplacedCreationData(project, blockTypeProject, blockTypeName);
                if (blockType) {
                    await blockType.ensureBlockAndTerrainLinks(project, creationData);
                }
            }
        }
        await project.save();
    }
    static async addItemTypeFromGallery(project, itemTypeProject, itemTypeName) {
        await ProjectCreateManager.copyGalleryPackFilesAndFixupIds(project, itemTypeProject, itemTypeName);
        await project.inferProjectItemsFromFiles(true);
        await project.save();
    }
    static async copyGalleryPackFilesAndFixupIds(project, galleryProject, newTypeName, messagerUpdater, dontOverwriteExistingFiles) {
        const files = galleryProject.fileList;
        if (newTypeName === undefined) {
            newTypeName = galleryProject.id;
        }
        if (files === undefined) {
            Log_1.default.unexpectedUndefined("AETFLS");
            return newTypeName;
        }
        let sourceBpFolder = undefined;
        let sourceRpFolder = undefined;
        if (galleryProject.gitHubRepoName === "bedrock-samples") {
            sourceBpFolder = await Database_1.default.getReleaseVanillaBehaviorPackFolder();
            sourceRpFolder = await Database_1.default.getReleaseVanillaResourcePackFolder();
        }
        else {
            const url = Utilities_1.default.ensureEndsWithSlash(CartoApp_1.default.contentRoot) +
                "res/samples/" +
                Utilities_1.default.ensureEndsWithSlash(galleryProject.gitHubOwner) +
                galleryProject.gitHubRepoName +
                "-" +
                Utilities_1.default.ensureEndsWithSlash(galleryProject.gitHubBranch ? galleryProject.gitHubBranch : "main") +
                (galleryProject.gitHubFolder ? Utilities_1.default.ensureNotStartsWithSlash(galleryProject.gitHubFolder) : "");
            const gh = new HttpStorage_1.default(url); //new GitHubStorage(carto.anonGitHub, gitHubRepoName, gitHubOwner, gitHubBranch, gitHubFolder);
            if (!gh.rootFolder.isLoaded) {
                await gh.rootFolder.load();
            }
            const bps = gh.rootFolder.folders["behavior_packs"];
            const rps = gh.rootFolder.folders["resource_packs"];
            if (!bps || !rps) {
                Log_1.default.unexpectedUndefined("AETFLT");
                return newTypeName;
            }
            if (!rps.isLoaded) {
                await rps.load();
            }
            if (!bps.isLoaded) {
                await bps.load();
            }
            if (rps.folderCount < 1 || bps.folderCount < 1) {
                Log_1.default.unexpectedUndefined("AETFLY");
                return newTypeName;
            }
            sourceBpFolder = bps.getFolderByIndex(0);
            sourceRpFolder = rps.getFolderByIndex(0);
        }
        const targetBpFolder = await project.ensureDefaultBehaviorPackFolder();
        const targetRpFolder = await project.ensureDefaultResourcePackFolder();
        if (!sourceBpFolder ||
            !sourceRpFolder ||
            !sourceBpFolder ||
            !sourceRpFolder ||
            !targetBpFolder ||
            !targetRpFolder) {
            Log_1.default.unexpectedUndefined("AETVA");
            return newTypeName;
        }
        // note: '"identifier"', was in this list for entity types, but was removed.
        let contentReplacements = ['"materials"'];
        for (const filePath of files) {
            if (filePath.startsWith("/behavior_pack")) {
                let subPath = undefined;
                if (filePath.startsWith("/behavior_pack/")) {
                    subPath = filePath.substring(14);
                }
                else {
                    const nextSlash = filePath.indexOf("/", 16);
                    if (nextSlash < 0) {
                        Log_1.default.unexpectedUndefined("AETVB");
                        return newTypeName;
                    }
                    subPath = filePath.substring(nextSlash);
                }
                const targetPath = ProjectCreateManager.replaceNamesInPath(subPath, project, galleryProject, newTypeName);
                const sourceFile = await sourceBpFolder.getFileFromRelativePath(subPath);
                if (!sourceFile) {
                    Log_1.default.debugAlert("Could not find file '" + subPath + "'  (GPFFIA)");
                }
                else {
                    const targetFile = await targetBpFolder.ensureFileFromRelativePath(targetPath);
                    let update = true;
                    if (dontOverwriteExistingFiles) {
                        const targetExists = await targetFile.exists();
                        if (targetExists) {
                            update = false;
                        }
                    }
                    if (update) {
                        if (!sourceFile.isContentLoaded) {
                            await sourceFile.loadContent();
                        }
                        let content = sourceFile.content;
                        if (typeof content === "string") {
                            content = ProjectCreateManager.replaceNamesInContent(content, project, galleryProject, newTypeName, contentReplacements);
                        }
                        if (content !== null) {
                            if (messagerUpdater) {
                                messagerUpdater("Updating '" + targetFile.fullPath + "'");
                            }
                            targetFile.setContent(content);
                        }
                    }
                }
            }
            else if (filePath.startsWith("/resource_pack")) {
                let subPath = undefined;
                if (filePath.startsWith("/resource_pack/")) {
                    subPath = filePath.substring(14);
                }
                else {
                    const nextSlash = filePath.indexOf("/", 16);
                    if (nextSlash < 0) {
                        Log_1.default.unexpectedUndefined("AETVC");
                        return newTypeName;
                    }
                    subPath = filePath.substring(nextSlash);
                }
                const targetPath = ProjectCreateManager.replaceNamesInPath(subPath, project, galleryProject, newTypeName);
                if (subPath.indexOf("cow.v2.render_controllers") >= 0) {
                    subPath = subPath.replace("cow.v2.render_controllers", "cow.v2.render_controllres"); // misspelling in source
                }
                const sourceFile = await sourceRpFolder.getFileFromRelativePath(subPath);
                if (!sourceFile) {
                    Log_1.default.debugAlert("Could not find file '" + subPath + "' (GPFFIB)");
                }
                else {
                    const targetFile = await targetRpFolder.ensureFileFromRelativePath(targetPath);
                    let update = true;
                    if (update) {
                        if (dontOverwriteExistingFiles) {
                            const targetExists = await targetFile.exists();
                            if (targetExists) {
                                update = false;
                            }
                        }
                        if (!sourceFile.isContentLoaded) {
                            await sourceFile.loadContent();
                        }
                        let content = sourceFile.content;
                        if (typeof content === "string") {
                            content = ProjectCreateManager.replaceNamesInContent(content, project, galleryProject, newTypeName, contentReplacements);
                        }
                        if (content !== null) {
                            if (messagerUpdater) {
                                messagerUpdater("Updating '" + targetFile.fullPath + "'");
                            }
                            targetFile.setContent(content);
                        }
                    }
                }
            }
        }
        return newTypeName;
    }
    static replaceNamesInPath(path, project, galleryProject, newName) {
        let pathReplacers = galleryProject.nameReplacers;
        if (!pathReplacers) {
            pathReplacers = [galleryProject.id];
        }
        newName = newName.toLowerCase();
        newName = newName.replace(/-/g, "_");
        newName = newName.replace(/ /g, "_");
        const tempName = Utilities_1.default.createRandomId(10);
        for (const pathReplacer of pathReplacers) {
            path = Utilities_1.default.replaceAll(path, "/" + pathReplacer + ".", "/" + tempName + ".");
            path = Utilities_1.default.replaceAll(path, "\\" + pathReplacer + ".", "\\" + tempName + ".");
            path = Utilities_1.default.replaceAll(path, "/" + pathReplacer + "/", "/" + tempName + "/");
            path = Utilities_1.default.replaceAll(path, "\\" + pathReplacer + "\\", "\\" + tempName + "\\");
            path = Utilities_1.default.replaceAll(path, "\\" + pathReplacer + "_", "\\" + tempName + "_");
            path = Utilities_1.default.replaceAll(path, "/" + pathReplacer + "_", "/" + tempName + "_");
            path = Utilities_1.default.replaceAll(path, "/" + pathReplacer + "_ico.", "/" + tempName + "_ico.");
            path = Utilities_1.default.replaceAll(path, "\\" + pathReplacer + "_ico.", "\\" + tempName + "_ico.");
            path = Utilities_1.default.replaceAll(path, "/" + pathReplacer + "_ico/", "/" + tempName + "_ico/");
            path = Utilities_1.default.replaceAll(path, "\\" + pathReplacer + "_ico\\", "\\" + tempName + "_ico\\");
        }
        path = Utilities_1.default.replaceAll(path, tempName, newName);
        return path;
    }
    static replaceNamesInContent(content, project, galleryProject, newName, replaceAllExclusions) {
        let replacers = galleryProject.nameReplacers;
        if (!replacers) {
            replacers = [galleryProject.id];
        }
        // copy & extend
        replacers = replacers.slice();
        replacers.push(exports.STANDARD_NAME_TOKEN);
        return this.replaceNamesInContentFromReplacers(content, project, replacers, newName, replaceAllExclusions);
    }
    static replaceNamesInContentFromReplacers(content, project, replacers, newName, replaceAllExclusions) {
        newName = newName.toLowerCase();
        newName = newName.replace(/-/g, "_");
        newName = newName.replace(/ /g, "_");
        const tempName = Utilities_1.default.createRandomLowerId(10);
        for (const replacer of replacers) {
            content = Utilities_1.default.replaceAll(content, "minecraft:" + replacer, project.effectiveDefaultNamespace + ":" + tempName);
            content = Utilities_1.default.replaceAll(content, "demo:" + replacer, project.effectiveDefaultNamespace + ":" + tempName);
            content = Utilities_1.default.replaceAll(content, "starter:" + replacer, project.effectiveDefaultNamespace + ":" + tempName);
            content = Utilities_1.default.replaceAll(content, "sample:" + replacer, project.effectiveDefaultNamespace + ":" + tempName);
            content = Utilities_1.default.replaceAllExceptInLines(content, ":" + replacer, ":" + tempName, replaceAllExclusions);
            content = Utilities_1.default.replaceAllExceptInLines(content, "/" + replacer, "/" + tempName, replaceAllExclusions);
            content = Utilities_1.default.replaceAllExceptInLines(content, "." + replacer, "." + tempName, replaceAllExclusions);
            content = Utilities_1.default.replaceAllExceptInLines(content, replacer + "_", tempName + "_", replaceAllExclusions);
            content = Utilities_1.default.replaceAllExceptInLines(content, '"' + replacer + '"', '"' + tempName + '"', replaceAllExclusions);
            for (const materialName of exports.MATERIAL_NAMES_TO_FIXUP) {
                content = Utilities_1.default.replaceAll(content, materialName + '": "' + tempName, materialName + '": "' + replacer);
            }
        }
        content = Utilities_1.default.replaceAll(content, tempName, newName);
        return content;
    }
}
exports.default = ProjectCreateManager;

//# sourceMappingURL=../maps/app/ProjectCreateManager.js.map
