"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addSettings = addSettings;
exports.createListReportConfig = createListReportConfig;
const ux_specification_types_1 = require("@sap/ux-specification-types");
const common_1 = require("../../../common");
const utils_1 = require("../utils");
const i18n_1 = require("../../../../i18n/i18n");
const i18next_1 = __importDefault(require("i18next"));
const extensionLogger_1 = require("../../../../extensionLogger");
const factory_1 = require("../../export/factory");
const utils_2 = require("../../utils/utils");
/**
 * Imports the content of annotation-based as well as custom columns.
 *
 * @param config - the configuration to be filled
 * @param importParameters  - object comprising all input data
 * @param factory - factory, for generating the access to reflect-metadata
 * @param pageType - page type
 * @param routingId - ID of the given page
 * @param configId - config id
 * @param viewId - view id in multi view mode
 */
function transferColumns(config, importParameters, factory, pageType, routingId, configId, viewId) {
    const schemaDefinitions = importParameters.jsonSchema.definitions;
    const lineItemsId = configId && configId !== `@${"com.sap.vocabularies.UI.v1.LineItem" /* UIAnnotationTerms.LineItem */}` ? configId : ux_specification_types_1.DefinitionName.LineItems;
    const lineItems = schemaDefinitions[lineItemsId];
    if (lineItems && Object.keys(lineItems.properties).length > 0) {
        config.columns = {};
        for (const columnKey in lineItems.properties) {
            const columnDefinition = schemaDefinitions[lineItemsId].properties[columnKey];
            const schemaPropertyName = columnDefinition.$ref.split(common_1.DEFINITION_LINK_PREFIX)[1].split('<')[0];
            config.columns[columnKey] = factory.createInstance(pageType, schemaPropertyName);
            const targetAnnotation = viewId || configId;
            (0, utils_1.importSettingsOfObject)(config.columns[columnKey], importParameters.manifest, schemaDefinitions[schemaPropertyName], routingId, [columnKey, targetAnnotation], targetAnnotation, importParameters.logger);
            (0, common_1.removeEmptyStructure)(config.columns, columnKey);
        }
        (0, common_1.removeEmptyStructure)(config, 'columns');
    }
    else {
        const views = importParameters.manifest['sap.ui5']?.routing?.targets?.[routingId]
            ?.options?.settings?.views;
        if (!views || views.paths.length < 1) {
            (0, extensionLogger_1.log)(importParameters.logger, {
                severity: "error" /* LogSeverity.Error */,
                message: i18next_1.default.t('NOLINEITEMS')
            });
        }
    }
}
/**
 * Import visual filters of list report.
 *
 * @param {ImportListReportV4Parameters} importParameters  - object comprising all input data
 * @param {v4.FilterBar} filterBarConfig - the configuration to be filled
 * @param {MetadataInstanceInterface} factory - factory, for generating the access to reflect-metadata
 * @param {PageTypeV4} pageType - page type
 * @param {string} routingId - page key in manifest
 */
function importVisualFilters(importParameters, filterBarConfig, factory, pageType, routingId) {
    const schemaDefinitions = importParameters.jsonSchema.definitions;
    const visualFilters = schemaDefinitions[ux_specification_types_1.DefinitionName.VisualFilters];
    filterBarConfig.visualFilters = {};
    if (typeof visualFilters === 'object') {
        for (const visualFilter in visualFilters.properties) {
            const filterDefinition = visualFilters.properties[visualFilter];
            if (typeof filterDefinition === 'object' && filterDefinition.$ref) {
                const definitionKey = (0, common_1.getDefinitionKey)(filterDefinition.$ref);
                const schemaPropertyName = definitionKey.split('<')[0];
                filterBarConfig.visualFilters[visualFilter] = factory.createInstance(pageType, schemaPropertyName);
                (0, utils_1.importSettingsOfObject)(filterBarConfig.visualFilters[visualFilter], importParameters.manifest, schemaDefinitions[definitionKey], routingId, [visualFilter]);
            }
        }
        (0, common_1.removeEmptyStructure)(filterBarConfig, 'visualFilters');
    }
}
/**
 * Import table toolbar actions of list report.
 *
 * @param importParameters  - object comprising all input data
 * @param tableConfig - configuration object for the table or table view
 * @param factory - factory, for generating the access to reflect-metadata
 * @param pageType - page type
 * @param routingId - The unique identifier for the routing configuration in the manifest.
 * @param columnDefinitionName - The name of the column definition to be used.
 * @param viewId - The identifier for the specific view in multi-view mode.
 */
function importActions(importParameters, tableConfig, factory, pageType, routingId, columnDefinitionName = ux_specification_types_1.DefinitionName.LineItems, viewId) {
    const schemaDefinitions = importParameters.jsonSchema.definitions;
    let targetAnnotation = viewId;
    if (!targetAnnotation &&
        [ux_specification_types_1.DefinitionName.LineItems, `${ux_specification_types_1.DefinitionName.LineItems}OfSPV::LineItem`].indexOf(columnDefinitionName) === -1) {
        targetAnnotation = `@${"com.sap.vocabularies.UI.v1.LineItem" /* UIAnnotationTerms.LineItem */}#${columnDefinitionName.split('::').pop()}`;
    }
    const actionsDefinition = schemaDefinitions[`${ux_specification_types_1.DefinitionName.Actions}<${columnDefinitionName}>`];
    if (typeof actionsDefinition === 'object') {
        for (const actionKey in actionsDefinition.properties) {
            const actionDefinition = actionsDefinition.properties[actionKey];
            if (typeof actionDefinition === 'object' && actionDefinition.$ref) {
                const definition = actionsDefinition?.['properties']?.[actionKey];
                const importActionParams = {
                    actionPropertyDefinition: definition,
                    appSchema: importParameters.jsonSchema,
                    factory,
                    actionsInConfig: tableConfig.toolBar.actions,
                    actionKey,
                    manifest: importParameters.manifest,
                    routingId,
                    targetAnnotation
                };
                (0, utils_2.importActionSettingsOfReference)(importActionParams);
            }
        }
    }
}
/**
 * Transfer toolbar settings of list report.
 *
 * @param importParameters - Object comprising all input data for the import process.
 * @param config - The configuration object to be filled with imported settings.
 * @param factory - Factory instance for generating metadata access objects.
 * @param pageType - The type of the page being processed (e.g., ListReport or AnalyticalListPage).
 * @param routingId - The unique identifier for the routing configuration in the manifest.
 * @param columnDefinitionName - The name of the column definition to be used.
 * @param viewId - The identifier for the specific view in multi-view mode, if applicable.
 */
function transferToolBar(importParameters, config, factory, pageType, routingId, columnDefinitionName = ux_specification_types_1.DefinitionName.LineItems, viewId) {
    const toolbarInstance = factory.createInstance(pageType, ux_specification_types_1.DefinitionName.ToolBar, {
        actions: {}
    });
    let table;
    if (!viewId && config && 'table' in config) {
        table = config.table;
    }
    else {
        table = config;
    }
    table.toolBar = toolbarInstance;
    (0, utils_1.importSettingsOfObject)(table.toolBar, importParameters.manifest, importParameters.jsonSchema.definitions[ux_specification_types_1.DefinitionName.ToolBarLR], routingId, []);
    importActions(importParameters, table, factory, pageType, routingId, columnDefinitionName, viewId);
    (0, common_1.removeEmptyStructure)(table.toolBar, 'actions');
    (0, common_1.removeEmptyStructure)(table, 'toolBar');
}
/**
 * Determines the target annotation of a list report view or defaultTemplateAnnotationPath.
 *
 * @param schemaDefinitions - app schema definitions
 * @param definitionName - current definition name
 * @returns the target annotation as string
 */
function determineTargetAnnotationOfView(schemaDefinitions, definitionName) {
    const lineItemAnnotation = schemaDefinitions[definitionName]?.[ux_specification_types_1.SchemaTag.annotationPath];
    const targetAnnotation = lineItemAnnotation?.substr(lineItemAnnotation.lastIndexOf('@'));
    return targetAnnotation;
}
/**
 * Import chart & table view of ALP.
 *
 * @param importParameters  - object comprising all input data
 * @param config - the configuration to be filled
 * @param factory - factory, for generating the access to reflect-metadata
 * @param pageType - page type
 * @param routingId - page key in manifest
 */
function importALPViews(importParameters, config, factory, pageType, routingId) {
    const schemaDefinitions = importParameters.jsonSchema.definitions;
    //chart view
    config.chart = factory.createInstance(pageType, ux_specification_types_1.DefinitionName.ALPChart);
    const chartDefinition = schemaDefinitions[ux_specification_types_1.DefinitionName.ALPChart];
    const chartAnnotationPath = chartDefinition[ux_specification_types_1.SchemaTag.annotationPath];
    (0, utils_1.importSettingsOfObject)(config.chart, importParameters.manifest, chartDefinition, routingId, [
        chartDefinition[ux_specification_types_1.SchemaTag.key],
        chartAnnotationPath?.substr(chartAnnotationPath.lastIndexOf('@'))
    ]);
    config.chart.toolBar = factory.createInstance(pageType, ux_specification_types_1.DefinitionName.ToolBar, { actions: {} });
    (0, utils_1.importSettingsOfObject)(config.chart.toolBar, importParameters.manifest, schemaDefinitions[ux_specification_types_1.DefinitionName.ViewChartToolBar], routingId, []);
    //table view
    const tableAnnotationPath = schemaDefinitions[ux_specification_types_1.DefinitionName.ALPTable][ux_specification_types_1.SchemaTag.annotationPath];
    if (tableAnnotationPath) {
        const tableDefinition = schemaDefinitions[ux_specification_types_1.DefinitionName.ALPTable];
        const tableConfig = (config.table = factory.createInstance(pageType, ux_specification_types_1.DefinitionName.ALPTable));
        transferToolBar(importParameters, config, factory, pageType, routingId);
        const configId = tableAnnotationPath.substr(tableAnnotationPath.lastIndexOf('@'));
        (0, utils_1.importSettingsOfObject)(tableConfig, importParameters.manifest, tableDefinition, routingId, [
            tableDefinition[ux_specification_types_1.SchemaTag.key],
            configId
        ]);
        //transfer columns
        transferColumns(tableConfig, importParameters, factory, pageType, routingId, undefined, configId);
    }
}
/**
 * Method received view definition name and returns view type.
 *
 * @param {string} definition  - definition name in schema.
 * @returns {DefinitionName | undefined} Resolved view type.
 */
function getViewTypeByDefinition(definition) {
    let viewType;
    if (definition.indexOf(ux_specification_types_1.DefinitionName.LRTableView) > -1) {
        viewType = ux_specification_types_1.DefinitionName.LRTableView;
    }
    else if (definition.indexOf(ux_specification_types_1.DefinitionName.LRChartView) > -1) {
        viewType = ux_specification_types_1.DefinitionName.LRChartView;
    }
    else if (definition === ux_specification_types_1.DefinitionName.TableViewExtension) {
        viewType = ux_specification_types_1.DefinitionName.TableViewExtension;
    }
    return viewType;
}
/**
 * Import table views of list report.
 *
 * @param importParameters  - object comprising all input data
 * @param config - the configuration to be filled
 * @param factory - factory, for generating the access to reflect-metadata
 * @param pageType - page type
 * @param routingId - page key in manifest
 */
function importLRViews(importParameters, config, factory, pageType, routingId) {
    const tableViewConfig = (config.table.views = factory.createInstance(pageType, ux_specification_types_1.DefinitionName.MultiTableModeV4));
    const schemaDefinitions = importParameters.jsonSchema.definitions;
    //Transfer settings on overall views' level
    (0, utils_1.importSettingsOfObject)(tableViewConfig, importParameters.manifest, schemaDefinitions[ux_specification_types_1.DefinitionName.MultiTableModeV4], routingId, []);
    const properties = schemaDefinitions[ux_specification_types_1.DefinitionName.MultiTableModeV4].properties;
    const sortedList = Object.entries(properties).sort((a, b) => a[1][ux_specification_types_1.SchemaTag.propertyIndex] - b[1][ux_specification_types_1.SchemaTag.propertyIndex]);
    for (const element of sortedList) {
        //process single views
        if (element[1]['$ref']) {
            const nextDefinition = element[1]['$ref'].split(common_1.DEFINITION_LINK_PREFIX)[1];
            const viewType = getViewTypeByDefinition(nextDefinition);
            const tableView = (tableViewConfig[element[0]] = factory.createInstance(pageType, viewType));
            const targetAnnotation = determineTargetAnnotationOfView(schemaDefinitions, nextDefinition);
            if (!schemaDefinitions[nextDefinition].entitySet) {
                (0, utils_1.importSettingsOfObject)(tableView, importParameters.manifest, schemaDefinitions[nextDefinition], routingId, [element[0], targetAnnotation]);
                if (viewType === ux_specification_types_1.DefinitionName.LRTableView) {
                    const definitionName = `${ux_specification_types_1.DefinitionName.LineItemsOfView}::${element[0]}`;
                    transferToolBar(importParameters, tableView, factory, pageType, routingId, definitionName, targetAnnotation);
                    transferColumns(tableView, importParameters, factory, pageType, routingId, definitionName, targetAnnotation);
                }
            }
            if (Object.keys(tableView).length === 0) {
                delete tableViewConfig[element[0]];
            }
        }
    }
    (0, common_1.removeEmptyStructure)(config.table, 'views');
}
/**
 * Fills the header actions in the config file of a V4 list report page.
 *
 * @param appSchema - app specific schema
 * @param listReportPageConfig - the configuration object for the list report page
 * @param factory - factory, for generating the access to reflect-metadata
 * @param manifest - manifest.json of the app
 * @param routingId - the unique identifier for the routing configuration in the manifest
 */
function transferHeaderActions(appSchema, listReportPageConfig, factory, manifest, routingId) {
    const definitionName = ux_specification_types_1.DefinitionName.HeaderActions;
    const actionType = ux_specification_types_1.PropertyName.header;
    const actions = appSchema.definitions[definitionName];
    if (typeof actions === 'object') {
        listReportPageConfig[actionType].actions = {};
        for (const actionKey in actions.properties) {
            const definition = actions.properties[actionKey];
            if (typeof definition === 'object' && definition.$ref) {
                const definitionKey = (0, common_1.getDefinitionKey)(definition.$ref);
                const actionDefinition = appSchema.definitions[definitionKey];
                const key = (0, common_1.getDefinitionKey)(actionDefinition.$ref || definition.$ref);
                listReportPageConfig[actionType].actions[actionKey] = factory.createInstance(ux_specification_types_1.PageTypeV4.ObjectPage, key);
                (0, utils_1.importSettingsOfObject)(listReportPageConfig[actionType].actions[actionKey], manifest, appSchema.definitions[key], routingId, [actionKey.replace('/', '??')]);
                (0, common_1.removeEmptyStructure)(listReportPageConfig.header, 'actions');
                (0, common_1.removeEmptyStructure)(listReportPageConfig, 'header');
            }
        }
    }
}
/**
 * Import custom filter fields of list report.
 *
 * @param {ImportListReportV4Parameters} importParameters  - object comprising all input data
 * @param {v4.FilterBar} filterBarConfig - the configuration to be filled
 * @param {MetadataInstanceInterface} factory - factory, for generating the access to reflect-metadata
 * @param {string} routingId - page key in manifest
 */
function importCustomFilterFields(importParameters, filterBarConfig, factory, routingId) {
    const schemaDefinitions = importParameters.jsonSchema.definitions;
    let filterFieldsProperties = {};
    for (const definition of [ux_specification_types_1.DefinitionName.SelectionFields, ux_specification_types_1.DefinitionName.CompactFilters]) {
        const filterFieldsSchema = schemaDefinitions[definition];
        if (typeof filterFieldsSchema === 'object' &&
            filterFieldsSchema.properties &&
            Object.keys(filterFieldsSchema.properties).length) {
            filterFieldsProperties = filterFieldsSchema.properties;
        }
    }
    for (const filterFieldId in filterFieldsProperties) {
        const schemaFilterField = filterFieldsProperties[filterFieldId];
        if (typeof schemaFilterField !== 'object' ||
            schemaFilterField.$ref !== common_1.DEFINITION_LINK_PREFIX + ux_specification_types_1.DefinitionName.CustomFilterField) {
            continue;
        }
        // Handle custom filter field
        const customFilterField = factory.createInstance(ux_specification_types_1.PageTypeV4.ListReport, ux_specification_types_1.DefinitionName.CustomFilterField);
        const sectionIdRef = schemaFilterField['$ref'].split(common_1.DEFINITION_LINK_PREFIX)[1];
        (0, utils_1.importSettingsOfObject)(customFilterField, importParameters.manifest, importParameters.jsonSchema.definitions[sectionIdRef], routingId, [filterFieldId]);
        if (!filterBarConfig.selectionFields) {
            filterBarConfig.selectionFields = {};
        }
        filterBarConfig.selectionFields[filterFieldId] = customFilterField;
    }
}
/**
 * Adds manifest settings to the config.json of LR or ALP V4.
 *
 * @param importParameters  - object comprising all input data
 * @param config - the configuration to be filled
 * @param factory - factory, for generating the access to reflect-metadata
 * @param pageType - page type
 * @param routingId - page key in manifest
 * @param schemaType - allows distinction of LR and ALP scenario
 */
function addSettings(importParameters, config, factory, pageType, routingId, schemaType) {
    // Transfer page level settings with sync rules
    (0, utils_1.importSettingsOfObject)(config, importParameters.manifest, importParameters.jsonSchema, routingId, []);
    config.header = factory.createInstance(pageType, ux_specification_types_1.DefinitionName.Header);
    (0, utils_1.importSettingsOfObject)(config.header, importParameters.manifest, importParameters.jsonSchema.definitions[ux_specification_types_1.DefinitionName.Header], routingId, []);
    transferHeaderActions(importParameters.jsonSchema, config, factory, importParameters.manifest, routingId);
    //FilterBar:
    config.filterBar = factory.createInstance(pageType, ux_specification_types_1.DefinitionName.FilterBar);
    (0, utils_1.importSettingsOfObject)(config.filterBar, importParameters.manifest, importParameters.jsonSchema.definitions[ux_specification_types_1.DefinitionName.FilterBar], routingId, []);
    importVisualFilters(importParameters, config.filterBar, factory, pageType, routingId);
    // Import custom filter fields
    importCustomFilterFields(importParameters, config.filterBar, factory, routingId);
    //Distinguish ALP table from LR table
    if (schemaType === ux_specification_types_1.SchemaType.ListReport) {
        let definitionName = ux_specification_types_1.DefinitionName.Table;
        let tableDefinition = importParameters.jsonSchema.definitions[definitionName];
        let columnDefinitionName;
        if (tableDefinition.$ref) {
            //(S)PV scenario ==> delegation, go to TableSPV
            definitionName = tableDefinition.$ref.split(common_1.DEFINITION_LINK_PREFIX)[1];
            tableDefinition = importParameters.jsonSchema.definitions[definitionName];
            columnDefinitionName = tableDefinition.properties.columns.$ref.split(common_1.DEFINITION_LINK_PREFIX)[1];
        }
        config.table = factory.createInstance(pageType, ux_specification_types_1.DefinitionName.Table);
        const targetAnnotation = determineTargetAnnotationOfView(importParameters.jsonSchema.definitions, definitionName);
        (0, utils_1.importSettingsOfObject)(config.table, importParameters.manifest, tableDefinition, routingId, [
            definitionName,
            targetAnnotation
        ]);
        //transfer toolbar
        transferToolBar(importParameters, config, factory, pageType, routingId, columnDefinitionName);
        //transfer columns
        transferColumns(config.table, importParameters, factory, pageType, routingId, columnDefinitionName, targetAnnotation);
        importLRViews(importParameters, config, factory, pageType, routingId);
    }
    else if (schemaType === ux_specification_types_1.SchemaType.AnalyticalListPage) {
        importALPViews(importParameters, config, factory, pageType, routingId);
    }
}
/**
 * Creates the configuration file content for a list report V4.
 *
 * @param importParameters  - object comprising all input data
 * @param schemaType - specifies whether the schema is for a List Report or Analytical List Page
 * @returns - the configuration (JSON) for the list report
 */
function createListReportConfig(importParameters, schemaType) {
    // Initialize i18next
    (0, i18n_1.initI18n)();
    if (!importParameters.jsonSchema) {
        return;
    }
    if (!importParameters.manifest[ux_specification_types_1.ManifestSection.ui5] || !importParameters.manifest[ux_specification_types_1.ManifestSection.ui5]['routing']) {
        (0, extensionLogger_1.log)(importParameters.logger, {
            severity: "error" /* LogSeverity.Error */,
            message: i18next_1.default.t('NOROUTING'),
            location: {
                path: ux_specification_types_1.MANIFESTPATH,
                range: [ux_specification_types_1.ManifestSection.ui5]
            }
        });
        return;
    }
    const v4Pages = importParameters.manifest[ux_specification_types_1.ManifestSection.ui5]['routing']['targets'];
    if (!v4Pages) {
        (0, extensionLogger_1.log)(importParameters.logger, {
            severity: "error" /* LogSeverity.Error */,
            message: i18next_1.default.t('NOTARGETS'),
            location: {
                path: ux_specification_types_1.MANIFESTPATH,
                range: [ux_specification_types_1.ManifestSection.ui5]
            }
        });
        return;
    }
    const factory = new factory_1.MetadataInstanceFactoryV4();
    //Instantiate Page
    const config = factory.createPageInstance(ux_specification_types_1.PageTypeV4.ListReport);
    for (const key in v4Pages) {
        const v4Page = v4Pages[key];
        const pageType = (0, common_1.getPageTypeV4)(v4Page);
        const matchesId = v4Page.name && key === importParameters.routingId;
        const matchesSchema = [ux_specification_types_1.PageTypeV4.ListReport, ux_specification_types_1.PageTypeV4.AnalyticalListPage].includes(pageType);
        if (matchesId && matchesSchema) {
            addSettings(importParameters, config, factory, ux_specification_types_1.PageTypeV4.ListReport, key, schemaType);
            break;
        }
    }
    return config;
}
//# sourceMappingURL=listReport.js.map