"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AngularTemplate = void 0;
const cli_core_1 = require("@igniteui/cli-core");
const path = require("path");
class AngularTemplate {
    /**
     * Creates a new AngularTemplate for a root path (pass in __dirname)
     */
    constructor(rootPath) {
        this.rootPath = rootPath;
        this.listInComponentTemplates = true;
        this.listInCustomTemplates = false;
        this.dependencies = [];
        this.framework = "angular";
        this.hasExtraConfiguration = false;
        this.packages = [];
        this.delimiters = cli_core_1.defaultDelimiters;
        this.fileSystem = new cli_core_1.FsFileSystem();
    }
    get templatePaths() {
        return [path.join(this.rootPath, "files")];
    }
    generateConfig(name, options) {
        if (options["modulePath"] && !cli_core_1.Util.fileExists(path.join(process.cwd(), `src\\app`, options["modulePath"]))) {
            cli_core_1.Util.error(`Wrong module path provided: ${options["modulePath"]}. No components were added!`);
            return Promise.resolve(false);
        }
        const config = Object.assign({}, options["extraConfig"], this.getBaseVariables(name));
        return config;
    }
    registerInProject(projectPath, name, options) {
        let modulePath = "app.module.ts";
        if (options && options.modulePath) {
            modulePath = options.modulePath;
        }
        // D.P. Don't use the top-level import as that chains import of typescript
        // which slows down execution of the entire component noticeably (template loading)
        // https://www.typescriptlang.org/docs/handbook/modules.html#dynamic-module-loading-in-nodejs
        // tslint:disable-next-line:variable-name
        const TsUpdate = 
        // tslint:disable-next-line:no-submodule-imports
        require("@igniteui/angular-templates").AngularTypeScriptFileUpdate;
        const componentPath = path.join(projectPath, `src/app/components/${this.folderName(name)}/${this.fileName(name)}.component.ts`);
        const className = `${cli_core_1.Util.className(cli_core_1.Util.nameFromPath(name))}Component`;
        if (!(options && options.skipRoute)) {
            //1) import the component class name,
            //2) and populate the Routes array with the path and component
            //for example: { path: "combo", component: ComboComponent }
            const routingModulePath = path.join(projectPath, "src/app/app-routing.module.ts");
            const routingModule = new TsUpdate(routingModulePath, false, { singleQuotes: false });
            routingModule.addRoute({
                path: this.folderName(name),
                identifierName: className,
                modulePath: cli_core_1.Util.relativePath(routingModulePath, componentPath, true, true),
                data: { text: cli_core_1.Util.nameFromPath(name) }
            });
            const content = routingModule.finalize();
            if (content) {
                // add to a finalize override in the NG File Update instead?
                cli_core_1.TypeScriptUtils.saveFile(routingModulePath, content);
            }
        }
        //3) add an import of the component class from its file location.
        //4) populate the declarations portion of the @NgModule with the component class name.
        const mainModulePath = path.join(projectPath, `src/app/${modulePath}`);
        const relativePath = cli_core_1.Util.relativePath(mainModulePath, componentPath, true, true);
        const mainModule = new TsUpdate(mainModulePath, false, { singleQuotes: false });
        mainModule.addNgModuleMeta({
            declare: [className],
            from: relativePath,
            export: modulePath !== "app.module.ts" ? [className] : []
        });
        const content = mainModule.finalize();
        if (content) {
            // add to a finalize override in the NG File Update instead?
            cli_core_1.TypeScriptUtils.saveFile(mainModulePath, content);
        }
        this.ensureSourceFiles(projectPath);
    }
    getExtraConfiguration() {
        return [];
    }
    setExtraConfiguration(extraConfigKeys) { }
    getBaseVariables(name) {
        const config = {};
        config["name"] = cli_core_1.Util.nameFromPath(name);
        config["ClassName"] = cli_core_1.Util.className(cli_core_1.Util.nameFromPath(name));
        config["path"] = this.folderName(name);
        config["filePrefix"] = this.fileName(name);
        config["description"] = this.description;
        config["cliVersion"] = cli_core_1.Util.version();
        config["camelCaseName"] = cli_core_1.Util.camelCase(name);
        if (this.widget) {
            config["widget"] = this.widget;
        }
        if (this.name) {
            config["nameMerged"] = this.name.replace(/ /g, "");
        }
        return config;
    }
    ensureSourceFiles(projectPath) {
        // tslint:disable-next-line:no-submodule-imports
        const components = require("@igniteui/cli-core/packages/components");
        const config = cli_core_1.ProjectConfig.getConfig();
        const files = config.project.sourceFiles;
        const dvDependencies = this.dependencies.filter(x => components.dv.indexOf(x) !== -1);
        if (dvDependencies.length && files.indexOf("infragistics.dv.js") === -1) {
            files.push("infragistics.dv.js");
            cli_core_1.ProjectConfig.setConfig(config);
        }
        if (this.dependencies.indexOf("igExcel") !== -1 && files.indexOf("infragistics.excel-bundled.js") === -1) {
            files.push("infragistics.excel-bundled.js");
            cli_core_1.ProjectConfig.setConfig(config);
        }
        if (this.dependencies.indexOf("igGridExcelExporter") !== -1
            && files.indexOf("modules/infragistics.gridexcelexporter.js") === -1) {
            files.push("modules/infragistics.gridexcelexporter.js");
            cli_core_1.ProjectConfig.setConfig(config);
        }
        // ensure ig-ts resource files registration
        if (this.projectType === "ig-ts") {
            this.registerSourceFiles(config, projectPath);
        }
    }
    /**
     * Register igniteui-angular-wrappers(ig-ts) resources under the project"s angular.json scripts and styles collections,
     * so these are picked by Angular"s internal webpack to build and serve
     */
    registerSourceFiles(config, projectPath) {
        const fs = cli_core_1.App.container.get(cli_core_1.FS_TOKEN);
        const sourceFiles = config.project.sourceFiles;
        const igniteuiSource = config.project.igniteuiSource;
        const themeCSS = "css/themes/infragistics/infragistics.theme.css";
        const infragisticsCSS = "css/structure/infragistics.css";
        let workspaceConfigObj;
        let updateFile = false;
        const workspacePath = path.join(projectPath, "angular.json");
        if (this.fileSystem.fileExists(workspacePath)) {
            workspaceConfigObj = JSON.parse(this.fileSystem.readFile(workspacePath));
            const scripts = workspaceConfigObj.projects[Object.keys(workspaceConfigObj.projects)[0]].architect.build.options.scripts;
            let styles = workspaceConfigObj.projects[Object.keys(workspaceConfigObj.projects)[0]].architect.build.options.styles;
            if (!styles.find(x => { var _a; return (_a = x.input) === null || _a === void 0 ? void 0 : _a.includes(themeCSS); }) || !styles.find(x => { var _a; return (_a = x.input) === null || _a === void 0 ? void 0 : _a.includes(infragisticsCSS); })) {
                styles = igniteuiSource === "@infragistics/ignite-ui-full/en/" ?
                    styles.push({ input: `${"@infragistics/ignite-ui-full/en/" + themeCSS}` }, { input: `${"@infragistics/ignite-ui-full/en/" + infragisticsCSS}` }) :
                    styles.push({ input: `${"ignite-ui/" + themeCSS}` }, { input: `${"ignite-ui/" + infragisticsCSS}` });
                updateFile = true;
            }
            for (const fileName of sourceFiles) {
                if (!scripts.find(x => x.bundleName === fileName)) {
                    scripts.push({
                        bundleName: fileName,
                        input: `${igniteuiSource + "/js/" + fileName}`
                    });
                    updateFile = true;
                }
            }
            if (updateFile) {
                fs.writeFile(workspacePath, cli_core_1.Util.formatAngularJsonOptions(workspaceConfigObj));
            }
        }
        else {
            cli_core_1.Util.log(`No angular.json file found! May have to manually add igniteui-angular-wrappers styles and scripts
							(infragistics.core.js, infragistics.lob.js, etc.) to the corresponding angular.json styles and scripts collections`);
        }
    }
    folderName(pathName) {
        //TODO: should remove the spaces
        const parts = path.parse(pathName);
        let folderName = pathName;
        if (parts.dir) {
            folderName = path.join(parts.dir, parts.name);
            folderName = folderName.replace(/\\/g, "/");
            // TODO: config-based "src/app"?
            const relative = path.join(process.cwd(), "src/app", folderName);
            // path.join will also resolve any ".." segments
            // so if relative result doesn't start with CWD it's out of project root
            if (!relative.startsWith(process.cwd())) {
                cli_core_1.Util.error(`Path ${"src/app/" + folderName} is not valid!`, "red");
                process.exit(1);
            }
            //clean up potential leading spaces in folder names (`path/	name`):
            folderName = folderName.replace(/\/\s+/g, "/");
        }
        return cli_core_1.Util.lowerDashed(folderName);
    }
    fileName(pathName) {
        const name = cli_core_1.Util.nameFromPath(pathName);
        return cli_core_1.Util.lowerDashed(name);
    }
}
exports.AngularTemplate = AngularTemplate;
