"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.CooperativeAddOnRequirementsGeneratorTest = void 0;
const ProjectInfoItem_1 = require("./ProjectInfoItem");
const IInfoItemData_1 = require("./IInfoItemData");
const StorageUtilities_1 = require("../storage/StorageUtilities");
const BehaviorManifestDefinition_1 = require("../minecraft/BehaviorManifestDefinition");
const IProjectItemData_1 = require("../app/IProjectItemData");
const Utilities_1 = require("../core/Utilities");
const ResourceManifestDefinition_1 = require("../minecraft/ResourceManifestDefinition");
const ProjectInfoUtilities_1 = require("./ProjectInfoUtilities");
const ProjectItemUtilities_1 = require("../app/ProjectItemUtilities");
const UniqueRegEx = new RegExp(/[a-zA-Z0-9]{2,}_[a-zA-Z0-9]{2,}:[\w]+/);
const GenericTermList = [
    "abilities",
    "actions",
    "adventure",
    "animals",
    "anims",
    "armor",
    "assets",
    "attachables",
    "banners",
    "base",
    "blocks",
    "book",
    "boss",
    "bosses",
    "bridge",
    "camping",
    "cars",
    "characters",
    "chests",
    "cinema",
    "cinematics",
    "cloud",
    "collectables",
    "collectibles",
    "custom_ui",
    "cut_scene",
    "cutscene",
    "deco",
    "decor",
    "dev",
    "dialogue",
    "dinos",
    "dinosaurs",
    "doors",
    "dragon",
    "dragons",
    "dummy",
    "effects",
    "enemies",
    "enemy",
    "entities",
    "entity",
    "env",
    "equipment",
    "events",
    "food",
    "furniture",
    "furnitures",
    "fx",
    "game_menu",
    "gameplay",
    "general",
    "glow",
    "guide",
    "guidebook",
    "inanimate",
    "interface",
    "internal",
    "intro",
    "item",
    "items",
    "launchers",
    "machines",
    "magic",
    "markers",
    "market",
    "marketing_banners",
    "mastermind",
    "mechanics",
    "menu",
    "menus",
    "minigames",
    "misc",
    "miscellaneous",
    "mob",
    "mobs",
    "monsters",
    "morphs",
    "mutant",
    "neutral",
    "npc",
    "npcs",
    "objectives",
    "particles",
    "passive",
    "passive_mobs",
    "pets",
    "platform",
    "player",
    "players",
    "portal",
    "portals",
    "preset",
    "projectile",
    "projectiles",
    "properties",
    "props",
    "recipe_models",
    "scanner",
    "script",
    "security",
    "sequences",
    "sfx",
    "shop",
    "skills",
    "sounds",
    "static_entity",
    "store",
    "structure",
    "structures",
    "systems",
    "tasks",
    "teams",
    "teleporter",
    "tnt",
    "tools",
    "towers",
    "trinkets",
    "tutorial",
    "ui",
    "user_interface",
    "util",
    "utilities",
    "vanilla",
    "vanilla_mob",
    "vehicle",
    "vehicles",
    "vr",
    "weapon",
    "weapons",
    "wrench",
    "opaque",
    "map",
    "on",
    "item",
    "player",
    "map",
    "charged",
    "beacon",
    "conduit",
    "moving",
    "banner",
    "bed",
    "cow",
    "chicken",
    "dragon",
    "ender",
    "enderman",
    "fang",
    "fireball",
    "mob",
    "warden",
    "village",
    "pattern",
    "wandering",
    "trial",
    "stray",
    "spider",
    "slime",
    "chest",
    "silverfish",
    "polar",
    "shield",
    "husk",
    "blaze",
    "axolotl",
];
// rule name/check. For validation errors, name should be a terse description of "your problem"
var CooperativeAddOnRequirementsGeneratorTest;
(function (CooperativeAddOnRequirementsGeneratorTest) {
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["noLooseFileInTypeFolder"] = 101] = "noLooseFileInTypeFolder";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["noCommonNamesInCreatorFolderName"] = 102] = "noCommonNamesInCreatorFolderName";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["noLooseFileInCreatorFolder"] = 104] = "noLooseFileInCreatorFolder";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["moreThanOneFolderInCreatorFolderBesidesMaybeCommon"] = 108] = "moreThanOneFolderInCreatorFolderBesidesMaybeCommon";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["noUnsupportedFolderNameInTypeFolder"] = 109] = "noUnsupportedFolderNameInTypeFolder";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["moreThanOneFolderInTypeFolder"] = 110] = "moreThanOneFolderInTypeFolder";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["noLooseFilesInTypeFolder"] = 111] = "noLooseFilesInTypeFolder";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["noDimensionElements"] = 131] = "noDimensionElements";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["noUiElements"] = 133] = "noUiElements";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["notOneBehaviorPackManifest"] = 160] = "notOneBehaviorPackManifest";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["notOneResourcePackManifest"] = 161] = "notOneResourcePackManifest";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["behaviorPackManifestNotValid"] = 163] = "behaviorPackManifestNotValid";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["resourcePackManifestNotValid"] = 164] = "resourcePackManifestNotValid";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["notOneDependencyFromBehaviorPackToResourcePack"] = 165] = "notOneDependencyFromBehaviorPackToResourcePack";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["dependencyFromBehaviorPackToResourcePackNotValid"] = 166] = "dependencyFromBehaviorPackToResourcePackNotValid";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["notOneDependencyFromResourcePackToBehaviorPack"] = 168] = "notOneDependencyFromResourcePackToBehaviorPack";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["dependencyFromResourcePackToBehaviorPackNotValid"] = 169] = "dependencyFromResourcePackToBehaviorPackNotValid";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["foundBehaviorPack"] = 200] = "foundBehaviorPack";
    CooperativeAddOnRequirementsGeneratorTest[CooperativeAddOnRequirementsGeneratorTest["noVibrantVisualsForNow"] = 210] = "noVibrantVisualsForNow";
})(CooperativeAddOnRequirementsGeneratorTest = exports.CooperativeAddOnRequirementsGeneratorTest || (exports.CooperativeAddOnRequirementsGeneratorTest = {}));
class CooperativeAddOnRequirementsGenerator {
    id = "CADDONREQ";
    title = "Cooperative Add-On Requirements";
    getTopicData(topicId) {
        return {
            title: ProjectInfoUtilities_1.default.getTitleFromEnum(CooperativeAddOnRequirementsGeneratorTest, topicId),
        };
    }
    async generate(project, contentIndex) {
        const items = [];
        let behaviorPackManifest = undefined;
        let behaviorPackItem = undefined;
        let resourcePackManifest = undefined;
        let resourcePackItem = undefined;
        const itemsCopy = project.getItemsCopy();
        for (const projectItem of itemsCopy) {
            if (projectItem.primaryFile) {
                if (ProjectItemUtilities_1.default.isVibrantVisualsRelated(projectItem)) {
                    // CADDONREQ210
                    items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.noVibrantVisualsForNow, `Found a Vibrant Visuals related file, which is not supported in cooperative add-ons (for now).`, projectItem));
                }
                if (projectItem.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) {
                    if (behaviorPackManifest) {
                        // CADDONREQ160
                        items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.notOneBehaviorPackManifest, `Found more than one behavior pack manifest in a cooperative add-on, which is not a best practice`, projectItem));
                    }
                    else {
                        items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.info, this.id, CooperativeAddOnRequirementsGeneratorTest.foundBehaviorPack, `Behavior pack manifest found.`, projectItem));
                    }
                    behaviorPackManifest = await BehaviorManifestDefinition_1.default.ensureOnFile(projectItem.primaryFile);
                    behaviorPackItem = projectItem;
                    await behaviorPackManifest?.load();
                }
                else if (projectItem.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson) {
                    if (resourcePackManifest) {
                        // CADDONREQ161
                        items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.notOneResourcePackManifest, `Found more than one resource pack manifest in a cooperative add-on, which is not a best practice`, projectItem));
                    }
                    resourcePackManifest = await ResourceManifestDefinition_1.default.ensureOnFile(projectItem.primaryFile);
                    resourcePackItem = projectItem;
                    await resourcePackManifest?.load();
                }
            }
        }
        if (!behaviorPackManifest || !behaviorPackManifest.definition) {
            // CADDONREQ163
            items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.behaviorPackManifestNotValid, `Did not find a valid behavior pack manifest.`, undefined));
        }
        if (!resourcePackManifest || !resourcePackManifest.definition) {
            //CADDONREQ164
            items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.resourcePackManifestNotValid, `Did not find a valid resource pack manifest.`, undefined));
        }
        if (behaviorPackManifest &&
            resourcePackManifest &&
            behaviorPackManifest.definition &&
            resourcePackManifest.definition) {
            const bpNonInternalDependency = behaviorPackManifest.getFirstNonScriptModuleDependency();
            if (!behaviorPackManifest.definition.dependencies ||
                behaviorPackManifest.getNonScriptModuleDependencyCount() !== 1) {
                // CADDONREQ165
                items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.notOneDependencyFromBehaviorPackToResourcePack, `Did not find exactly one dependency on the corresponding resource pack in the behavior pack manifest.`, behaviorPackItem, behaviorPackManifest.getNonScriptModuleDependencyCount()));
            }
            else if (!bpNonInternalDependency ||
                !bpNonInternalDependency.uuid ||
                !Utilities_1.default.uuidEqual(bpNonInternalDependency.uuid, resourcePackManifest.definition.header.uuid)) {
                // CADDONREQ166
                items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.dependencyFromBehaviorPackToResourcePackNotValid, `Behavior pack manifest does not have a proper dependency on the resource pack identifier.`, behaviorPackItem));
            }
            if (!resourcePackManifest.definition.dependencies || resourcePackManifest.definition.dependencies.length !== 1) {
                // CADDONREQ168
                items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.notOneDependencyFromResourcePackToBehaviorPack, `Did not find exactly one dependency on the corresponding behavior pack in the resource pack manifest.`, resourcePackItem));
            }
            else if (!resourcePackManifest.definition.dependencies[0].uuid ||
                !Utilities_1.default.uuidEqual(resourcePackManifest.definition.dependencies[0].uuid, behaviorPackManifest.definition.header.uuid)) {
                // CADDONREQ169
                items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.dependencyFromResourcePackToBehaviorPackNotValid, `Resource pack manifest does not have a proper dependency on the behavior pack identifier.`, behaviorPackItem));
            }
        }
        const bpFolder = await project.getDefaultBehaviorPackFolder();
        if (bpFolder) {
            await this.generateFromBehaviorPackFolder(project, bpFolder, items);
        }
        const rpFolder = await project.getDefaultResourcePackFolder();
        if (rpFolder) {
            await this.generateFromResourcePackFolder(project, rpFolder, items);
        }
        return items;
    }
    summarize(info, infoSet) { }
    async generateFromBehaviorPackFolder(project, folder, items) {
        await folder.load();
        for (const folderName in folder.folders) {
            const childFolder = folder.folders[folderName];
            const folderNameCanon = StorageUtilities_1.default.canonicalizeName(folderName);
            if (folderNameCanon === "dimensions") {
                // CADDONREQ131
                items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.noDimensionElements, `Found dimensions in a cooperative add-on, which is not a best practice.`, undefined));
            }
            if (childFolder && !folder.errorStatus) {
                if (folderNameCanon === "structures") {
                    await this.generateFromFirstLevelFolderCreator_Game(project, childFolder, items);
                }
                else if (folderNameCanon !== "texts" &&
                    folderNameCanon !== "entities" &&
                    folderNameCanon !== "features" &&
                    folderNameCanon !== "feature_rules" &&
                    folderNameCanon !== "particles" &&
                    folderNameCanon !== "items" &&
                    folderNameCanon !== "scripts" &&
                    folderNameCanon !== "recipes" &&
                    folderNameCanon !== "spawn_rules" &&
                    folderNameCanon !== "animations" &&
                    folderNameCanon !== "animation_controllers" &&
                    folderNameCanon !== "render_controllers" &&
                    folderNameCanon !== "blocks") {
                    await this.generateFromFirstLevelFolderCreatorNameGameName(project, childFolder, items);
                }
            }
        }
    }
    async generateFromResourcePackFolder(project, folder, items) {
        await folder.load();
        for (const folderName in folder.folders) {
            const childFolder = folder.folders[folderName];
            const folderNameCanon = StorageUtilities_1.default.canonicalizeName(folderName);
            if (folderNameCanon === "ui") {
                // CADDONREQ133
                items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.noUiElements, `Found ui elements in a cooperative add-on, which is not supported`, undefined));
            }
            if (childFolder && !folder.errorStatus) {
                if (folderNameCanon !== "texts" &&
                    folderNameCanon !== "entity" &&
                    folderNameCanon !== "items" &&
                    folderNameCanon !== "particles" &&
                    folderNameCanon !== "materials" &&
                    folderNameCanon !== "blocks" &&
                    folderNameCanon !== "models" &&
                    folderNameCanon !== "attachables" &&
                    folderNameCanon !== "render_controllers" &&
                    folderNameCanon !== "animation_controllers" &&
                    folderNameCanon !== "animations") {
                    await this.generateFromFirstLevelFolderCreatorNameGameName(project, childFolder, items);
                }
            }
        }
    }
    static isNameGenericTerm(name) {
        name = StorageUtilities_1.default.canonicalizeName(name);
        return GenericTermList.includes(name);
    }
    static isNamespacedIdentifier(id) {
        let identifierSplit = id.split(":");
        if (identifierSplit.length !== 2) {
            return false;
        }
        if (identifierSplit[0].length < 2 || identifierSplit[1].length < 2) {
            return false;
        }
        return this.isNamespacedString(identifierSplit[0]);
    }
    static isNamespacedString(name) {
        let tokens = name.split("_");
        if (tokens.length < 2) {
            return false;
        }
        return tokens[0].length >= 2 && tokens[1].length >= 2;
    }
    static isCommonMaterialName(name) {
        let tokens = name.split("_");
        if (tokens.length < 3) {
            return true;
        }
        return GenericTermList.includes(tokens[0]);
    }
    static isUniqueNamespaceOrShortName(name) {
        name = StorageUtilities_1.default.canonicalizeName(name);
        if (name.length < 3) {
            return false;
        }
        return UniqueRegEx.test(name);
    }
    async generateFromFirstLevelFolderCreator_Game(project, folder, items) {
        await folder.load();
        for (const fileName in folder.files) {
            if (!this.isPerPackCatalogFile(folder.name, fileName)) {
                const file = folder.files[fileName];
                const projectItem = file?.extendedPath ? project.getItemByExtendedOrProjectPath(file?.extendedPath) : undefined;
                // CADDONREQ111
                items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.noLooseFilesInTypeFolder, `Found a loose file in the ${folder.name} folder. Should only see files in the folder ${folder.name}\\creatorshortname_gamename\\`, projectItem, fileName));
            }
        }
        let folderCount = 0;
        for (const folderName in folder.folders) {
            const folderNameCanon = StorageUtilities_1.default.canonicalizeName(folderName);
            folderCount++;
            if (CooperativeAddOnRequirementsGenerator.isUniqueNamespaceOrShortName(folderNameCanon)) {
                // CADDONREQ109
                items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.noUnsupportedFolderNameInTypeFolder, `Found an add-on-blocked folder '${folderName}' in a parent folder pack\\${folder.name}. Should be named 'creatorshortname' and not a common term`, undefined, folderName));
            }
        }
        if (folderCount > 1) {
            // CADDONREQ110
            items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.moreThanOneFolderInTypeFolder, `Folder '${folder.name}' has more than one subfolder, which is not supported. There should only be one folder in pack\\${folder.name}\\<studioname>_<mygamename>`, undefined, folder.name));
        }
    }
    isPerPackCatalogFile(folderName, fileName) {
        const fileNameCanon = StorageUtilities_1.default.canonicalizeName(fileName);
        if ((folderName !== "functions" || fileNameCanon !== "tick.json") &&
            (folderName !== "textures" ||
                (fileNameCanon !== "flipbook_textures.json" &&
                    fileNameCanon !== "item_textures.json" &&
                    fileNameCanon !== "blocks.json" &&
                    fileNameCanon !== "block.json" &&
                    fileNameCanon !== "textures_list.json" &&
                    fileNameCanon !== "texture_list.json" &&
                    fileNameCanon !== "terrain_textures.json" &&
                    fileNameCanon !== "item_texture.json" &&
                    fileNameCanon !== "terrain_texture.json")) &&
            (folderName !== "item_catalog" || fileNameCanon !== "crafting_item_catalog.json") &&
            (folderName !== "sounds" ||
                (fileNameCanon !== "sound_definitions.json" &&
                    fileNameCanon !== "sounds.json" &&
                    fileNameCanon !== "music_definitions.json"))) {
            return false;
        }
        return true;
    }
    async generateFromFirstLevelFolderCreatorNameGameName(project, folder, items) {
        await folder.load();
        for (const fileName in folder.files) {
            if (!this.isPerPackCatalogFile(folder.name, fileName)) {
                const file = folder.files[fileName];
                const projectItem = file?.extendedPath ? project.getItemByExtendedOrProjectPath(file?.extendedPath) : undefined;
                // CADDONREQ101
                items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.noLooseFileInTypeFolder, `Found a loose file in the ${folder.name} folder. Should only see files in the folder ${folder.name}\\creatorshortname\\gamename\\`, projectItem, fileName));
            }
        }
        for (const folderName in folder.folders) {
            const folderNameCanon = StorageUtilities_1.default.canonicalizeName(folderName);
            if (CooperativeAddOnRequirementsGenerator.isNameGenericTerm(folderNameCanon)) {
                // CADDONREQ102
                items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.noCommonNamesInCreatorFolderName, `Found an cooperative add-on common name folder '${folderName}' in a parent folder pack\\${folder.name}. Should be named 'creatorshortname' and not a common term`, undefined, folderName));
            }
            const childFolder = folder.folders[folderName];
            if (childFolder) {
                await this.generateFromSecondLevelFolderGameName(project, folder.name, childFolder, items);
            }
        }
    }
    async generateFromSecondLevelFolderGameName(project, parentFolderName, folder, items) {
        await folder.load();
        for (const fileName in folder.files) {
            const file = folder.files[fileName];
            const projectItem = file?.extendedPath ? project.getItemByExtendedOrProjectPath(file.extendedPath) : undefined;
            // CADDONREQ104
            items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.noLooseFileInCreatorFolder, `Found a loose file '${fileName}' in ${parentFolderName}\\${folder.name}. Files should only be in the folder ${parentFolderName}\\${folder.name}\\<mygamename>`, projectItem, fileName));
        }
        let folderCount = 0;
        for (const childFolderName in folder.folders) {
            const folderNameCanon = StorageUtilities_1.default.canonicalizeName(childFolderName);
            if (folderNameCanon !== "common") {
                folderCount++;
            }
        }
        if (folderCount > 1) {
            // CADDONREQ108
            items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, CooperativeAddOnRequirementsGeneratorTest.moreThanOneFolderInCreatorFolderBesidesMaybeCommon, `Secondary folder '${folder.name}' in ${parentFolderName} has more than one subfolder (besides 'common'), which is not supported. There should only be one folder (plus optionally 'common') in pack\\${parentFolderName}\\${folder.name}\\<mygamename>`, undefined, folder.name));
        }
    }
}
exports.default = CooperativeAddOnRequirementsGenerator;

//# sourceMappingURL=../maps/info/CooperativeAddOnRequirementsGenerator.js.map
