"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getResponsiveTableCellsFragment = exports.getColumnFragmentContent = exports.getSingleColumnContent = exports.getFragmentJsContent = exports.getFragmentContent = exports.getViewContent = exports.getControllerContent = exports.renderTemplate = exports.CONFIG = exports.ViewTypes = void 0;
exports.getViewFileName = getViewFileName;
const path_1 = require("path");
const ux_specification_types_1 = require("@sap/ux-specification-types");
const ejs_1 = require("ejs");
const fs_1 = require("fs");
const fe_fpm_writer_1 = require("@sap-ux/fe-fpm-writer");
const templatesPath = (0, path_1.join)(__dirname, 'templates');
var ViewTypes;
(function (ViewTypes) {
    ViewTypes["XML"] = "xml";
    ViewTypes["HTML"] = "html";
    ViewTypes["JSON"] = "json";
})(ViewTypes || (exports.ViewTypes = ViewTypes = {}));
exports.CONFIG = {
    ['AnalyticalTableColumnsExtension.xml']: {
        getData: (generateId) => {
            return {
                ids: {
                    label: generateId('Label'),
                    text: generateId('Text'),
                    customData: generateId('CustomData')
                }
            };
        }
    },
    ['fragment.xml']: {
        getData: (generateId) => {
            return {
                ids: {
                    verticalLayout: generateId('VerticalLayout'),
                    text: generateId('Text'),
                    button: generateId('Button')
                }
            };
        }
    },
    ['GridTableColumnsExtension.xml']: {
        getData: (generateId) => {
            return {
                ids: {
                    label: generateId('Label'),
                    text: generateId('Text'),
                    customData: generateId('CustomData')
                }
            };
        }
    },
    ['ResponsiveTableColumnsExtension.xml']: {
        getData: (generateId) => {
            return {
                ids: {
                    text: generateId('Text'),
                    customData: generateId('CustomData')
                }
            };
        }
    },
    ['TreeTableColumnsExtension.xml']: {
        getData: (generateId) => {
            return {
                ids: {
                    label: generateId('Label'),
                    text: generateId('Text'),
                    customData: generateId('CustomData')
                }
            };
        }
    },
    ['view.xml']: {
        getData: (generateId) => {
            return {
                ids: {
                    app: generateId('App'),
                    page: generateId('Page'),
                    label: generateId('Label')
                }
            };
        }
    }
};
/**
 * Method which reads passed template and renders it using passed template object.
 *
 * @param {string} templatePath - Path to template.
 * @param {{ [key: string]: string }} templateData - Template data object.
 * @param {IdGeneratorFunction} generateId - function to generate ids for new entries in the fragment.
 * @returns {string} the rendered template's string
 */
const renderTemplate = (templatePath, templateData, generateId) => {
    const template = (0, fs_1.readFileSync)(templatePath, 'utf8');
    const templateKey = (0, fe_fpm_writer_1.getRelativeTemplateComponentPath)(templatePath);
    if (generateId && exports.CONFIG[templateKey] && typeof exports.CONFIG[templateKey].getData === 'function') {
        const additionalData = exports.CONFIG[templateKey].getData(generateId);
        templateData = { ...templateData, ...additionalData };
    }
    return (0, ejs_1.render)(template, templateData);
};
exports.renderTemplate = renderTemplate;
/**
 * Method escapes view name.
 *
 * @param {string} name - View's name.
 * @returns {string} Escaped view name.
 */
const escapeViewName = (name) => {
    // Remove all special characters
    return name.replace(/[^\w\s-]/gi, '');
};
/**
 * Method which reads passed template and renders it using passed template object.
 *
 * @param {string} name - View's name.
 * @param {string} namespace - Application namespace.
 * @param fcl - Indicates whether the Flexible Column Layout (FCL) template should be used.
 * @param newControllerRouting - Specifies if the new controller routing should be applied.
 * @returns {string} the rendered template's string
 */
const getControllerContent = (name, namespace, fcl = false, newControllerRouting = false) => {
    const templateData = {
        name: namespace + '.' + escapeViewName(name),
        newControllerRouting
    };
    return (0, exports.renderTemplate)((0, path_1.join)(templatesPath, fcl ? 'controllerFcl.js' : 'controller.js'), templateData);
};
exports.getControllerContent = getControllerContent;
/**
 * Method which reads passed template and renders it using passed template object.
 *
 * @param {string} name - View's name.
 * @param {string} namespace - Application namespace.
 * @param {ViewTypes} sourceType - View's source type like XML, HTML, JSON or JS.
 * @param {IdGeneratorFunction} generateId - function to generate ids for new entries in the fragment.
 * @param {boolean} [controller] - Generate controller.
 * @param {boolean} [page] - Is view should contains page structure or not - page structure uses 'sap.m.App' in view template.
 * @returns {string} the rendered template's string
 */
const getViewContent = (name, namespace, sourceType, generateId, controller = false, page = true) => {
    const escapedName = escapeViewName(name);
    const templateData = {
        name: escapedName,
        controllerName: '',
        page
    };
    if (controller) {
        templateData.controllerName = namespace + '.controller.' + escapedName;
    }
    return (0, exports.renderTemplate)((0, path_1.join)(templatesPath, 'view.' + sourceType), templateData, generateId);
};
exports.getViewContent = getViewContent;
/**
 * Method which reads template for fragment and returns rendered result of fragment.
 *
 * @param {string} name - View's name.
 * @param {string} namespace - Application namespace.
 * @param {ViewTypes} sourceType - View's source type like XML, HTML, JSON or JS.
 * @param {IdGeneratorFunction} generateId - function to generate ids for new entries in the fragment.
 * @param {boolean} handler - JS handler.
 * @returns {string} the rendered template's string
 */
const getFragmentContent = (name, namespace, sourceType, generateId, handler = false) => {
    const escapedName = escapeViewName(name);
    const templateData = {
        name: escapedName,
        handler: ''
    };
    if (handler) {
        templateData.handler = `${namespace.replace(/\./g, '/')}/${ux_specification_types_1.DirName.Fragment}/${escapedName}`;
    }
    return (0, exports.renderTemplate)((0, path_1.join)(templatesPath, 'fragment.' + sourceType), templateData, generateId);
};
exports.getFragmentContent = getFragmentContent;
/**
 * Method which reads passed template and renders it using passed template object.
 *
 * @returns {string} the rendered template's string
 */
const getFragmentJsContent = () => {
    return (0, exports.renderTemplate)((0, path_1.join)(templatesPath, 'fragment.js'), {});
};
exports.getFragmentJsContent = getFragmentJsContent;
/**
 * Method which reads the template for a single column extension that shall be added to a fragment.
 *
 * @param column - data (from config) to be inserted in the template
 * @param template - The type of view template (e.g., XML, HTML, JSON).
 * @param {IdGeneratorFunction} generateId - function to generate ids for new entries in the fragment.
 * @returns {string} the rendered template's string
 */
const getSingleColumnContent = (column, template, generateId) => {
    const templateData = {
        id: column.id,
        text: column.text,
        columnKey: column.columnKey,
        columnIndex: column.columnIndex !== undefined ? column.columnIndex.toString() : undefined,
        leadingProperty: column.leadingProperty
    };
    return (0, exports.renderTemplate)((0, path_1.join)(templatesPath, template + '.xml'), templateData, generateId);
};
exports.getSingleColumnContent = getSingleColumnContent;
/**
 * Method which reads the template for a column extension fragment and returns rendered result of fragment.
 *
 * @param customColumns - array of all column extensions' data
 * @param templateType - The type of view template (e.g., XML, HTML, JSON).
 * @param {IdGeneratorFunction} generateId - function to generate ids for new entries in the fragment.
 * @returns {string} the rendered template's string
 */
const getColumnFragmentContent = (customColumns, templateType, generateId) => {
    let fragment = '';
    fragment = '<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns:table="sap.ui.table" xmlns="sap.m">';
    if (customColumns) {
        for (const column of customColumns) {
            const newContent = (0, exports.getSingleColumnContent)(column, templateType, generateId);
            fragment = fragment + '\n' + newContent;
        }
    }
    return fragment + '\n' + '</core:FragmentDefinition>';
};
exports.getColumnFragmentContent = getColumnFragmentContent;
/**
 * Creates the content for a ResponsiveTableCellsExtension fragment.
 *
 * @param customColumns - list of custom columns; for each of them a dummy entry gets created in the view content.
 * @param generateId - function to generate ids for new entries in the fragment.
 * @returns {string} the rendered template's string
 */
const getResponsiveTableCellsFragment = (customColumns, generateId) => {
    let fragment = '<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m">';
    let validatedIds = [];
    if (customColumns) {
        customColumns.forEach(() => {
            const newId = generateId('Text', validatedIds);
            validatedIds.push(newId);
            // use same approach as json2xml - use 4 spaces for fragment children elements
            fragment = fragment + `\n    <Text id="${newId}" text="Placeholder"/>`;
        });
    }
    return fragment + '\n' + '</core:FragmentDefinition>';
};
exports.getResponsiveTableCellsFragment = getResponsiveTableCellsFragment;
/**
 * Method to construct full name of view or fragment.
 *
 * @param {string} name Shorten name of view or fragment.
 * @param {boolean} isFragment Is fragment or view.
 * @param {ViewTypes} viewType type of view or fragment.
 * @returns {string} Full path of view or fragment name.
 */
function getViewFileName(name, isFragment, viewType = ViewTypes.XML) {
    return isFragment ? `${name}.fragment.${viewType}` : `${name}.view.${viewType}`;
}
//# sourceMappingURL=view-controller-generator.js.map