"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addSelectionFields = addSelectionFields;
exports.analyzeViewAnnotation = analyzeViewAnnotation;
exports.generateListReportSchemaV4 = generateListReportSchemaV4;
const utils_1 = require("../utils/utils");
const ux_specification_types_1 = require("@sap/ux-specification-types");
const i18next_1 = __importDefault(require("i18next"));
const extensionLogger_1 = require("../../../extensionLogger");
const common_1 = require("../../common");
const ROOT_PROPERTIES_ORDER = ['header', 'filterBar', 'chart', 'table'];
const UILINEITEM = '@UI.LineItem';
/**
 * Adds the selection fields to the app schema, as properties of the FilterBar.
 *
 * @param {EntityType} entityType - the entity type as part of the AVT ConvertedMetadata
 * @param {Definition} appSchema - the app specific schema that shall get enhanced
 * @param {AnnotationTerm<SelectionFields>} selectionFieldsAnnotation - the UI.SelectionField annotation
 * @param {Definition} [selectionFieldsDefinition] - Schema definitions of selection fields
 * @param {string} [qualifier] - Qualifier for SelectionFields
 * @returns {Definition} - the updated selection fields definition
 */
function addSelectionFields(entityType, appSchema, selectionFieldsAnnotation, selectionFieldsDefinition, qualifier) {
    if (!selectionFieldsDefinition) {
        selectionFieldsDefinition = appSchema.definitions[ux_specification_types_1.DefinitionName.SelectionFields];
        selectionFieldsDefinition.additionalProperties = false;
        selectionFieldsDefinition.properties = {};
    }
    if (entityType) {
        selectionFieldsDefinition[ux_specification_types_1.SchemaTag.annotationPath] = (0, common_1.createAnnotationPath)(entityType.fullyQualifiedName, "com.sap.vocabularies.UI.v1.SelectionFields" /* UIAnnotationTerms.SelectionFields */, qualifier);
    }
    let i = 0;
    selectionFieldsAnnotation?.forEach((selectionField) => {
        let description = selectionField.value;
        const fieldDefinition = 'SelectionField::' + (0, common_1.prepareRef)(selectionField.value);
        if (selectionField.type === 'PropertyPath') {
            description = (0, common_1.getLabelForPropertyPath)(selectionField, entityType);
        }
        selectionFieldsDefinition.properties[fieldDefinition] = {
            $ref: common_1.DEFINITION_LINK_PREFIX + fieldDefinition
        };
        selectionFieldsDefinition.properties[fieldDefinition][ux_specification_types_1.SchemaTag.propertyIndex] = i;
        const dataType = (0, common_1.determineDataType)(selectionField);
        appSchema.definitions[fieldDefinition] = {
            type: 'object',
            properties: {},
            description,
            additionalProperties: false,
            ...(dataType && { dataType })
        };
        appSchema.definitions[fieldDefinition][ux_specification_types_1.SchemaTag.isViewNode] = true;
        appSchema.definitions[fieldDefinition][ux_specification_types_1.SchemaTag.keys] = [
            { name: ux_specification_types_1.SchemaKeyName.value, value: `${selectionField.value}` }
        ];
        if (selectionField.$target?.fullyQualifiedName.indexOf('@') > -1) {
            appSchema.definitions[fieldDefinition][ux_specification_types_1.SchemaTag.target] = selectionField.$target.fullyQualifiedName
                .split('@')[0]
                .split('/')[0];
        }
        else if (selectionField.$target?.fullyQualifiedName) {
            appSchema.definitions[fieldDefinition][ux_specification_types_1.SchemaTag.target] =
                selectionField.$target.fullyQualifiedName.split('/')[0];
        }
        appSchema.definitions[fieldDefinition][ux_specification_types_1.SchemaTag.annotationType] = selectionField?.type;
        appSchema.definitions[fieldDefinition][ux_specification_types_1.SchemaTag.annotationPath] = `${selectionFieldsDefinition[ux_specification_types_1.SchemaTag.annotationPath]}/${i}`;
        i++;
    });
    return selectionFieldsDefinition;
}
/**
 * Returns visual filters (if defined) from manifest page.
 *
 * @param v4Page - actual page in the manifest
 * @returns - The visual filters object if defined, otherwise undefined.
 */
function getVisualFilters(v4Page) {
    const selectionFields = v4Page.options.settings?.controlConfiguration?.[`@${"com.sap.vocabularies.UI.v1.SelectionFields" /* UIAnnotationTerms.SelectionFields */}`]?.['filterFields'];
    if (selectionFields) {
        const visualFilters = {};
        Object.keys(selectionFields).forEach((field) => {
            if (!selectionFields[field].template) {
                visualFilters[field] = selectionFields[field];
            }
        });
        return Object.keys(visualFilters).length > 0 ? visualFilters : undefined;
    }
}
/**
 * Collects indexes of selection fields and entityProperties to sort visual filters.
 *
 * @param selectionFields - The selection fields annotation to be processed
 * @param entityType - the entity type as part of the AVT ConvertedMetadata
 * @returns - An array of property names sorted by their index.
 */
function getPropertiesIndex(selectionFields, entityType) {
    const properties = [];
    selectionFields?.forEach((selectionField) => properties.push(selectionField.value));
    if (entityType) {
        entityType.entityProperties.forEach((property) => !properties.includes(property.name) ? properties.push(property.name) : undefined);
    }
    return properties;
}
/**
 * Adds visual filters to the app schema, as properties of the FilterBar.
 *
 * @param {EntityType} entityType - the entity type as part of the AVT ConvertedMetadata
 * @param {Definition} appSchema - the app specific schema that shall get enhanced
 * @param visualFiltersManifest - the UI.SelectionFields under controlConfiguration
 * @param selectionFields - The selection fields annotation to be processed
 */
function addVisualFilters(entityType, appSchema, visualFiltersManifest, selectionFields) {
    const propertiesIndex = getPropertiesIndex(selectionFields, entityType);
    const visualFilters = appSchema.definitions[ux_specification_types_1.DefinitionName.VisualFilters];
    visualFilters.properties = {};
    for (const fieldName in visualFiltersManifest) {
        const filterField = visualFiltersManifest[fieldName];
        // No custom filter field support in visual filters
        if (!filterField.template) {
            const visualFiltersField = (visualFilters.properties[fieldName] = {
                $ref: (0, common_1.getFacetDefinitionLink)(ux_specification_types_1.DefinitionName.VisualFilter, fieldName)
            });
            const propertyIndex = propertiesIndex.indexOf(fieldName);
            if (propertyIndex !== -1) {
                visualFiltersField[ux_specification_types_1.SchemaTag.propertyIndex] = propertyIndex;
            }
            const filterDefinition = (0, common_1.parseSchemaDefinition)(ux_specification_types_1.DefinitionName.VisualFilter, fieldName, appSchema);
            if (filterField.visualFilter?.valueList) {
                filterDefinition[ux_specification_types_1.SchemaTag.annotationPath] = `${fieldName}/@${filterField.visualFilter.valueList}`;
            }
            const annotationLabel = entityType?.entityProperties
                ?.find((property) => property.name === fieldName)
                ?.annotations?.Common?.Label?.toString();
            filterDefinition.description = annotationLabel || fieldName;
            filterDefinition[ux_specification_types_1.SchemaTag.keys] = [{ name: ux_specification_types_1.SchemaKeyName.value, value: fieldName }];
        }
    }
}
/**
 * Method updates schema for custom filter fields:
 * 1. Enables creation of custom filter fields.
 * 2. Populates custom filter fields from manifest to schema.
 *
 * @param appSchema - the app specific schema that shall get enhanced
 * @param selectionFieldsDefinition - schema of selection fields which should contain custom filter fields
 * @param v4Page - actual page in the manifest
 */
function applyCustomFilterFields(appSchema, selectionFieldsDefinition, v4Page) {
    selectionFieldsDefinition.additionalProperties = {
        $ref: `#/definitions/${ux_specification_types_1.DefinitionName.CustomFilterField}`
    };
    (0, utils_1.addCustomFilterFieldDefinition)(appSchema, selectionFieldsDefinition, v4Page);
    const customSectionDefinition = appSchema.definitions[ux_specification_types_1.DefinitionName.CustomFilterFieldPosition];
    if (typeof customSectionDefinition === 'object') {
        (0, common_1.addDescriptiveEnumDefinition)(appSchema, selectionFieldsDefinition, {
            schema: customSectionDefinition,
            property: 'anchor'
        }, {
            resolveDefinition: true,
            keyProperties: [ux_specification_types_1.SchemaKeyName.value, ux_specification_types_1.SchemaKeyName.key],
            descriptionAsFallback: true
        });
    }
}
/**
 * Adds selection fields or compact/visual filters to filter bar.
 *
 * @param entityType - actual entity type (AVT information)
 * @param appSchema - app-specific JSON schema
 * @param v4Page - actual page in the manifest
 * @param alias - the given alias or namespace of the OData annotations
 */
function addFilterBar(entityType, appSchema, v4Page, alias) {
    const visualFilters = getVisualFilters(v4Page);
    const selectionFields = alias && entityType?.annotations?.[alias]?.SelectionFields;
    let selectionFieldsDefinition;
    // Hide visualFilters/selectionFields depending on existing visual filters
    if (visualFilters) {
        appSchema.definitions[ux_specification_types_1.DefinitionName.SelectionFields][ux_specification_types_1.SchemaTag.hidden] = true;
        appSchema.definitions[ux_specification_types_1.DefinitionName.SelectionFields]['properties'] = {};
        selectionFieldsDefinition = appSchema.definitions[ux_specification_types_1.DefinitionName.CompactFilters];
        selectionFieldsDefinition.additionalProperties = false;
        selectionFieldsDefinition.properties = {};
        addVisualFilters(entityType, appSchema, visualFilters, selectionFields);
    }
    else {
        const filterBar = appSchema.definitions[ux_specification_types_1.DefinitionName.FilterBar];
        filterBar.properties['initialLayout'][ux_specification_types_1.SchemaTag.hidden] = true;
        filterBar.properties['layout'][ux_specification_types_1.SchemaTag.hidden] = true;
        appSchema.definitions[ux_specification_types_1.DefinitionName.CompactFilters][ux_specification_types_1.SchemaTag.hidden] = true;
        appSchema.definitions[ux_specification_types_1.DefinitionName.VisualFilters][ux_specification_types_1.SchemaTag.hidden] = true;
    }
    selectionFieldsDefinition = addSelectionFields(entityType, appSchema, selectionFields, selectionFieldsDefinition);
    // Apply custom filter fields
    applyCustomFilterFields(appSchema, selectionFieldsDefinition, v4Page);
}
/**
 *
 * @param appSchema - The app JSON schema to be updated
 * @param schemaIdForActions - The schema ID for the actions to be defined
 * @param annotations - The UI annotations for the given entity type
 * @param targetAnnotation - The target annotation for the actions
 * @param entityType - The entity type as part of the AVT ConvertedMetadata
 */
function defineActions(appSchema, schemaIdForActions, annotations, targetAnnotation, entityType) {
    appSchema.definitions[schemaIdForActions] = JSON.parse(JSON.stringify(appSchema.definitions['Actions']));
    const actions = appSchema.definitions[schemaIdForActions];
    actions.properties = {};
    actions.additionalProperties = false;
    const chartAnnotation = annotations[targetAnnotation?.split(`${ux_specification_types_1.UIVOCABULARY}.`)[1]];
    if (chartAnnotation && chartAnnotation.Actions) {
        let i = 0;
        chartAnnotation.Actions.forEach((actionRecord) => {
            const actionDefinition = (0, common_1.prepareRef)(`${ux_specification_types_1.DefinitionName.ChartToolBarAction}<${actionRecord.Action}>`);
            const description = (0, common_1.getDataFieldDescription)(actionRecord, entityType);
            const prefix = actionRecord.$Type.split(`${ux_specification_types_1.UIVOCABULARY}.`)[1];
            const action = (actions.properties[`${prefix}::${actionRecord.Action}`] = {
                $ref: common_1.DEFINITION_LINK_PREFIX + actionDefinition,
                description
            });
            //Add tags
            action[ux_specification_types_1.SchemaTag.propertyIndex] = i;
            action[ux_specification_types_1.SchemaTag.annotationType] = actionRecord.$Type;
            action[ux_specification_types_1.SchemaTag.annotationPath] = `/${actionRecord.fullyQualifiedName}`;
            //as ChartToolBarAction is an empty object, copy ViewToolBarAction and remove properties
            appSchema.definitions[actionDefinition] = JSON.parse(JSON.stringify(appSchema.definitions[ux_specification_types_1.DefinitionName.ViewToolBarAction]));
            appSchema.definitions[actionDefinition].properties = {};
            appSchema.definitions[actionDefinition][ux_specification_types_1.SchemaTag.annotationPath] = actionRecord.fullyQualifiedName;
            i++;
        });
    }
}
/**
 * Finds the right visualization for a given view.
 *
 * @param allVisualizations - list of visualizations for the given (S)PV
 * @param namespace - namespace for the UI annotations
 * @param viewKey - view key: primary, secondary, or anything else; may also be undefined. The first visualization is taken in this case.
 * @param visualizationType - allows to find the right visualization if there are many.
 * @returns the value of the first fitting visualization
 */
function findTheRightVisualization(allVisualizations, namespace, viewKey, visualizationType) {
    let visualization, visualizationObject, targetAnnotation;
    if (allVisualizations) {
        if (viewKey === 'primary') {
            visualizationObject = allVisualizations.find((vis) => {
                return vis['value'].indexOf('Chart') > -1;
            });
        }
        else if (viewKey === 'secondary') {
            visualizationObject = allVisualizations.find((vis) => {
                return vis['value'].indexOf(ux_specification_types_1.FacetBase.LineItem) > -1;
            });
        }
        else {
            if (visualizationType) {
                visualizationObject = allVisualizations.find((v) => v['value'].indexOf(visualizationType) > -1);
            }
            else {
                visualizationObject = allVisualizations[0];
            }
        }
        visualization =
            typeof visualizationObject?.['value'] === 'string'
                ? (0, common_1.replaceNamespaces)(visualizationObject['value'])
                : undefined;
        if (visualizationObject?.['$target']?.fullyQualifiedName) {
            targetAnnotation = `/${namespace}/${visualizationObject['$target'].fullyQualifiedName.split(namespace)[1]}`;
        }
        else if (visualization) {
            targetAnnotation = `/${namespace}/` + visualization.replace(`UI`, ux_specification_types_1.UIVOCABULARY);
        }
    }
    return { visualization, targetAnnotation };
}
/**
 * An annotationPath must be analyzed, to find the right target annotation and visualization.
 *
 * @param namespace - The namespace for the UI annotations.
 * @param annotationPath - The path of the annotation to be analyzed.
 * @param annotationAVT - The annotation object from the AVT (Annotation Vocabulary Tools).
 * @param viewKey - The key to distinguish between different view types.
 * @returns An object containing the visualization, target annotation, and chart title.
 */
function analyzeChartAnnotation(namespace, annotationPath, annotationAVT, viewKey) {
    const visualization = '@UI.Chart';
    const targetAnnotationFullName = `/${namespace}/@${annotationPath}`;
    let chartTitle;
    if (annotationAVT['Title']) {
        chartTitle = annotationAVT['Title'];
    }
    else {
        chartTitle = `Chart View (${viewKey})`;
    }
    return { visualization, targetAnnotation: targetAnnotationFullName, chartTitle };
}
/**
 * Analyzes a SelectionPresentationVariant, to find the right target annotation and visualization.
 *
 * @param uiAnnotations - The UI annotations of the given entity type.
 * @param namespace - The namespace for the UI annotations.
 * @param viewKey - The key to distinguish between different view types.
 * @param visualizationType - The type of visualization to find the right one if there are multiple.
 * @param logger - The logger instance for logging messages.
 * @param title - The title to be displayed for the view.
 * @returns An object containing the visualization, target annotation, namespace, and title.
 */
function analyzeSPVforView(uiAnnotations, namespace, viewKey, visualizationType, logger, title) {
    let { visualization, targetAnnotation } = findTheRightVisualization(uiAnnotations.PresentationVariant?.Visualizations, namespace, viewKey, visualizationType);
    if (!visualization) {
        (0, extensionLogger_1.log)(logger, {
            severity: "error" /* LogSeverity.Error */,
            message: i18next_1.default.t('NOVISUALIZATIONS')
        });
        visualization = UILINEITEM; // default visualization
        targetAnnotation = `/${namespace}/` + visualization.replace(`UI`, ux_specification_types_1.UIVOCABULARY); // default targetAnnotation
    }
    title = title || `View (${viewKey})`;
    return { visualization, targetAnnotation, namespace, title };
}
/**
 * An annotationPath must be analyzed, to find the right target annotation and visualization.
 *
 * @param annotationPath - given annotationPath
 * @param uIAnnotations - annotations of UI namespace of the given entityType
 * @param serviceAVT Combined service metadata, as returned by annotation vocabularies tools.
 * @param viewKey - allows to distinguish the different view types (LR or ALP)
 * @param visualizationType - allows to find the right visualization if there are many.
 * @param logger - extension logger.
 * @returns visualization: string describing the visualization of the annotation,
 *          targetAnnotation: the target annotation behind the visualization
 *          namespace: namespace of the annotation,
 *          title: title to be shown, derived from the annotation
 */
function analyzeViewAnnotation(annotationPath, uIAnnotations, serviceAVT, viewKey, visualizationType, logger) {
    let namespace = undefined, title;
    const annotationInManifest = annotationPath?.split(`${ux_specification_types_1.UIVOCABULARY}.`)[1];
    const annotationAVT = annotationInManifest && uIAnnotations[annotationInManifest];
    if (!annotationAVT) {
        return { visualization: undefined, targetAnnotation: undefined, namespace, title: `View (${viewKey})` };
    }
    title = annotationAVT.Text;
    namespace = annotationAVT.fullyQualifiedName.split(ux_specification_types_1.UIVOCABULARYALPHADOT)[0];
    if (annotationInManifest.startsWith('PresentationVariant')) {
        const { visualization, targetAnnotation } = findTheRightVisualization(annotationAVT.Visualizations, namespace, viewKey, visualizationType);
        title = title || `View (${viewKey})`;
        return { visualization, targetAnnotation, namespace, title };
    }
    else if (annotationInManifest.startsWith('SelectionPresentationVariant')) {
        return analyzeSPVforView(annotationAVT, namespace, viewKey, visualizationType, logger, title);
    }
    else if (annotationInManifest.startsWith('SelectionVariant')) {
        const visualization = UILINEITEM;
        const targetAnnotation = `/${namespace}/@${"com.sap.vocabularies.UI.v1.LineItem" /* UIAnnotationTerms.LineItem */}`;
        title = title || `Table View (${viewKey})`;
        return { visualization, targetAnnotation, namespace, title };
    }
    else if (annotationInManifest.startsWith('LineItem')) {
        let visualization = UILINEITEM;
        if (annotationAVT.qualifier) {
            visualization += `#${annotationAVT.qualifier}`;
        }
        const targetAnnotation = annotationPath.substring(0, 1) === '@'
            ? `/${namespace}/${annotationPath}`
            : `/${namespace}/@${annotationPath}`;
        title = title || `Table View (${viewKey})`;
        return { visualization, targetAnnotation, namespace, title };
    }
    else if (annotationInManifest.startsWith('Chart')) {
        const { visualization, targetAnnotation, chartTitle } = analyzeChartAnnotation(namespace, annotationPath, annotationAVT, viewKey);
        return { visualization, targetAnnotation, namespace, title: chartTitle };
    }
    return { visualization: undefined, targetAnnotation: undefined, namespace, title: `View (${viewKey})` };
}
/**
 * Adds the ALP chart view to the app-specific schema.
 *
 * @param {Definition} appSchema - app-specific JSON schema
 * @param chartAnnotationPath - The annotation path for the chart view
 * @param targetAnnotation - target annotation of the chart view, as determined by analyzeViewAnnotation
 * @param annotations - UI annotations, as determined by AVT
 */
function addALPChartView(appSchema, chartAnnotationPath, targetAnnotation, annotations) {
    const chartView = appSchema.definitions[ux_specification_types_1.DefinitionName.ALPChartView];
    appSchema.definitions[ux_specification_types_1.DefinitionName.ALPChart] = JSON.parse(JSON.stringify(chartView));
    delete appSchema.definitions[ux_specification_types_1.DefinitionName.ALPChart][ux_specification_types_1.SchemaTag.isViewNode];
    if (targetAnnotation) {
        appSchema.definitions[ux_specification_types_1.DefinitionName.ALPChart][ux_specification_types_1.SchemaTag.annotationPath] = targetAnnotation;
    }
    appSchema.definitions[ux_specification_types_1.DefinitionName.ALPChart].properties.annotationPath[ux_specification_types_1.SchemaTag.hidden] = true;
    chartView.properties.annotationPath[ux_specification_types_1.SchemaTag.hidden] = true;
    chartView.additionalProperties = false;
    chartView.description = `Chart (key: primary)`;
    chartView.title = `Chart`;
    chartView.$ref = `${common_1.DEFINITION_LINK_PREFIX}${ux_specification_types_1.DefinitionName.ALPChart}`;
    if (chartAnnotationPath) {
        const viewAnnotation = chartAnnotationPath.split(ux_specification_types_1.UIVOCABULARYDOT)[1];
        if (annotations[viewAnnotation]) {
            const pathParts = annotations[viewAnnotation].fullyQualifiedName.split('@');
            chartView[ux_specification_types_1.SchemaTag.annotationPath] = `/${pathParts[0]}/@${pathParts[1]}`;
        }
        else {
            // Add message about unexisting annotation path
            (0, common_1.addMessageToSchema)(chartView, i18next_1.default.t('UNEXISTING_ANNOTATION_PATH'));
        }
    }
    chartView[ux_specification_types_1.SchemaTag.artifactType] = ux_specification_types_1.ArtifactType.Manifest;
    chartView[ux_specification_types_1.SchemaTag.key] = 'primary';
    chartView[ux_specification_types_1.SchemaTag.keys] = [{ name: ux_specification_types_1.SchemaKeyName.key, value: 'primary' }];
}
/**
 * Adds the ALP views to the app-specific schema.
 *
 * @param appSchema - app-specific JSON schema
 * @param viewsPaths - views' paths' section in the manifest
 * @param generateParameters - list of API input parameters
 * @param templateAnnotation - defaultTemplateAnnotationPath as registered in manifest
 * @param v4Page - actual page in the manifest
 * @param tableDefinitionName - The name of the table definition in the schema
 */
function addALPViews(appSchema, viewsPaths, generateParameters, templateAnnotation, v4Page, tableDefinitionName) {
    const annotations = generateParameters.entityType?.annotations.UI;
    //1. Chart View
    const chartAnnotationPath = viewsPaths?.[0]?.['primary']?.[0]?.[ux_specification_types_1.SchemaTag.annotationPath];
    const { targetAnnotation } = analyzeViewAnnotation(chartAnnotationPath, annotations, generateParameters.serviceAVT, 'primary', undefined, generateParameters.logger);
    addALPChartView(appSchema, chartAnnotationPath, targetAnnotation, annotations);
    // Copy toolbar
    const schemaIdForActions = `Actions<ALPChart>`;
    appSchema.definitions[ux_specification_types_1.DefinitionName.ViewChartToolBar].properties.actions['$ref'] =
        common_1.DEFINITION_LINK_PREFIX + schemaIdForActions;
    defineActions(appSchema, schemaIdForActions, annotations, targetAnnotation, generateParameters.entityType);
    //2. Table View
    const { visualization: tableVisualization, targetAnnotation: target } = analyzeViewAnnotation(viewsPaths?.[0]?.['secondary']?.[0]?.[ux_specification_types_1.SchemaTag.annotationPath], annotations, generateParameters.serviceAVT, 'secondary', undefined, generateParameters.logger);
    const tableDefinition = appSchema.definitions[tableDefinitionName];
    if (tableVisualization || templateAnnotation) {
        tableDefinition.properties.toolBar['$ref'] = `${common_1.DEFINITION_LINK_PREFIX}${ux_specification_types_1.DefinitionName.ToolBarLR}`;
        // Switch from generic column to specific definition
        tableDefinition.properties['columns'] = {
            $ref: common_1.DEFINITION_LINK_PREFIX + ux_specification_types_1.DefinitionName.LineItems
        };
        tableDefinition.properties.annotationPath[ux_specification_types_1.SchemaTag.hidden] = true;
    }
    else {
        tableDefinition.properties = {};
    }
    const tableView = appSchema.definitions[ux_specification_types_1.DefinitionName.ALPTableView];
    appSchema.definitions[ux_specification_types_1.DefinitionName.ALPTable] = JSON.parse(JSON.stringify(tableView));
    delete appSchema.definitions[ux_specification_types_1.DefinitionName.ALPTable][ux_specification_types_1.SchemaTag.isViewNode];
    tableView.additionalProperties = false;
    tableView.description = `Table (key: secondary)`;
    tableView.title = `Table`;
    if (tableVisualization) {
        delete tableView.properties;
        tableView.$ref = `${common_1.DEFINITION_LINK_PREFIX}${ux_specification_types_1.DefinitionName.ALPTable}`;
    }
    else if (!templateAnnotation) {
        tableView.properties = {};
    }
    tableView[ux_specification_types_1.SchemaTag.artifactType] = ux_specification_types_1.ArtifactType.Manifest;
    let annotationTerm, viewAnnotation;
    if (tableVisualization && tableVisualization.indexOf(ux_specification_types_1.FacetBase.LineItem) > -1) {
        annotationTerm = tableVisualization.split('.')[1];
        viewAnnotation = viewsPaths[0]['secondary'][0].annotationPath.split(ux_specification_types_1.UIVOCABULARYDOT)[1];
    }
    else if (templateAnnotation) {
        annotationTerm = viewAnnotation = templateAnnotation.split(ux_specification_types_1.UIVOCABULARYDOT)[1];
    }
    if (annotationTerm) {
        const dataForLineItem = {
            isObjectPage: false,
            appSchema,
            lineItemAnnotation: generateParameters.entityType?.annotations.UI[annotationTerm],
            entityType: generateParameters.entityType,
            oDataServiceAVT: generateParameters.serviceAVT,
            lineItemId: ux_specification_types_1.DefinitionName.LineItems
        };
        (0, utils_1.addLineItemsTypeToSchema)(dataForLineItem, ux_specification_types_1.DefinitionName.ViewTableColumn);
        if (target) {
            appSchema.definitions[ux_specification_types_1.DefinitionName.ALPTable][ux_specification_types_1.SchemaTag.annotationPath] = target;
        }
        const pathParts = annotations[viewAnnotation].fullyQualifiedName.split('@');
        tableView[ux_specification_types_1.SchemaTag.annotationPath] = `/${pathParts[0]}/@${pathParts[1]}`;
        tableView[ux_specification_types_1.SchemaTag.key] = 'secondary';
        tableView[ux_specification_types_1.SchemaTag.keys] = [{ name: ux_specification_types_1.SchemaKeyName.key, value: 'secondary' }];
    }
    (0, utils_1.addCustomColumnDefinition)(appSchema, v4Page, generateParameters.logger);
    // Table toolbar actions with custom actions
    const schemaIdForToolbarActions = `${ux_specification_types_1.DefinitionName.Actions}<${(0, common_1.prepareRef)(ux_specification_types_1.DefinitionName.LineItems)}>`;
    (0, utils_1.addCustomActionDefinition)(appSchema, v4Page, generateParameters.logger, undefined, schemaIdForToolbarActions);
    (0, utils_1.addEnumForActionAnchor)(appSchema, schemaIdForToolbarActions, ux_specification_types_1.DefinitionName.CustomActionPosition);
}
/**
 * Modifies the app schema, adds the right line chart settings.
 *
 * @param inputParameters - list of input parameters as collected by the calling instance
 * @param annotations - UI annotations of the given entityType
 * @returns the ID for the chart view in schema
 */
function addViewChartDefinitions(inputParameters, annotations) {
    const idForChart = `${ux_specification_types_1.DefinitionName.LRChartView}<${inputParameters.viewKey}>`;
    inputParameters.appSchema.definitions[idForChart] = JSON.parse(JSON.stringify(inputParameters.appSchema.definitions[ux_specification_types_1.DefinitionName.LRChartView]));
    delete inputParameters.appSchema.definitions[idForChart][ux_specification_types_1.SchemaTag.isViewNode];
    inputParameters.appSchema.definitions[idForChart][ux_specification_types_1.SchemaTag.annotationPath] = inputParameters.targetAnnotation;
    if (inputParameters.navPropName) {
        inputParameters.appSchema.definitions[idForChart]['navigationProperty'] = inputParameters.navPropName;
    }
    //Copy toolbar
    const idForToolbar = `${ux_specification_types_1.DefinitionName.ViewChartToolBar}<${inputParameters.viewKey}>`;
    inputParameters.appSchema.definitions[idForToolbar] = JSON.parse(JSON.stringify(inputParameters.appSchema.definitions[ux_specification_types_1.DefinitionName.ViewChartToolBar]));
    inputParameters.appSchema.definitions[idForChart]['properties'].toolBar.$ref =
        `${common_1.DEFINITION_LINK_PREFIX}${idForToolbar}`;
    //Copy actions
    const schemaIdForActions = `${ux_specification_types_1.DefinitionName.Actions}<${inputParameters.viewKey}>`;
    defineActions(inputParameters.appSchema, schemaIdForActions, annotations, inputParameters.targetAnnotation, inputParameters.targetEntityType);
    inputParameters.appSchema.definitions[idForToolbar]['properties'][ux_specification_types_1.PropertyName.actions]['$ref'] =
        `${common_1.DEFINITION_LINK_PREFIX}${schemaIdForActions}`;
    return idForChart;
}
/**
 * Adds the definition of a chart view to the app schema.
 *
 * @param inputParameters - list of input parameters as collected by the calling instance
 * @param UIAnnotations - AVT UI annotations of the given entity type
 * @param appSchema - app schema
 * @param viewsDefinition - the views definition in app schema (MultiTableModeV4)
 * @param viewKey - view key
 * @param title - view title
 */
function addViewChart(inputParameters, UIAnnotations, appSchema, viewsDefinition, viewKey, title) {
    const idForChart = addViewChartDefinitions(inputParameters, UIAnnotations);
    appSchema.definitions[idForChart].properties.annotationPath[ux_specification_types_1.SchemaTag.hidden] = true;
    appSchema.definitions[idForChart].properties.index[ux_specification_types_1.SchemaTag.hidden] = true;
    appSchema.definitions[idForChart].properties.entitySet[ux_specification_types_1.SchemaTag.hidden] = true;
    const titleOnHover = `Chart View (key: ${viewKey})`;
    viewsDefinition.properties[viewKey] = {
        $ref: `${common_1.DEFINITION_LINK_PREFIX}${idForChart}`,
        description: title ? title : titleOnHover,
        title: titleOnHover
    };
}
/**
 * Modifies the app schema, adds the right line item settings as derived from the visualization.
 *
 * @param inputParameters - list of input parameters as collected by the calling instance
 * @param viewsDefinition - the views definition in app schema (MultiTableModeV4)
 * @param visualization - visualization from the given (S)PV
 * @param templateAnnotation - defaultTemplateAnnotationPath as registered in manifest
 * @param {GenerateAppSchemaParameters} generateParameters - list of API input parameters
 */
function addViewLineItems(inputParameters, viewsDefinition, visualization, templateAnnotation, generateParameters) {
    const tableId = `${ux_specification_types_1.DefinitionName.LRTableView}<${inputParameters.viewKey}>`;
    const viewId = `${ux_specification_types_1.DefinitionName.LineItemsOfView}::${inputParameters.viewKey}`;
    const lrTableView = (0, common_1.parseSchemaDefinition)(ux_specification_types_1.DefinitionName.LRTableView, inputParameters.viewKey, inputParameters.appSchema);
    delete lrTableView[ux_specification_types_1.SchemaTag.isViewNode];
    lrTableView[ux_specification_types_1.SchemaTag.annotationPath] = inputParameters.targetAnnotation;
    if (inputParameters.navPropName) {
        lrTableView['navigationProperty'] = inputParameters.navPropName;
    }
    if (inputParameters.entitySet) {
        lrTableView['entitySet'] = inputParameters.entitySet;
    }
    //Copy toolbar
    (0, common_1.addDefinitionRef)(lrTableView.properties.toolBar, ux_specification_types_1.DefinitionName.ToolBar, viewId);
    const title = `Table View (key: ${inputParameters.viewKey})`;
    viewsDefinition.properties[inputParameters.viewKey] = {
        $ref: `${common_1.DEFINITION_LINK_PREFIX}${tableId}`,
        description: inputParameters.title || title,
        title
    };
    (0, common_1.addDefinitionRef)(lrTableView.properties.columns, viewId);
    lrTableView.properties.annotationPath[ux_specification_types_1.SchemaTag.hidden] = true;
    lrTableView.properties.index[ux_specification_types_1.SchemaTag.hidden] = true;
    lrTableView.properties.entitySet[ux_specification_types_1.SchemaTag.hidden] = true;
    const annotationTerm = visualization?.split('.')[1] || templateAnnotation.split(ux_specification_types_1.UIVOCABULARYDOT)[1];
    const dataForLineItem = {
        isObjectPage: false,
        appSchema: inputParameters.appSchema,
        lineItemAnnotation: inputParameters.targetEntityType?.annotations.UI[annotationTerm],
        entityType: inputParameters.targetEntityType,
        oDataServiceAVT: generateParameters.serviceAVT,
        lineItemId: viewId
    };
    (0, utils_1.addLineItemsTypeToSchema)(dataForLineItem, ux_specification_types_1.DefinitionName.ViewTableColumn, ux_specification_types_1.DefinitionName.ViewCustomColumn, ux_specification_types_1.DefinitionName.ViewCustomAction);
}
/**
 * Adds the schema tags to a given view.
 *
 * @param viewsDefinition - the views definition in app schema (MultiTableModeV4)
 * @param viewKey - key property of the view
 * @param namespace - target namespace for annotations
 * @param view - the given view
 */
function addTagsToView(viewsDefinition, viewKey, namespace, view) {
    viewsDefinition.properties[viewKey][ux_specification_types_1.SchemaTag.isViewNode] = true;
    viewsDefinition.properties[viewKey][ux_specification_types_1.SchemaTag.annotationPath] = namespace
        ? `/${namespace}/@${view[ux_specification_types_1.SchemaTag.annotationPath]}`
        : undefined;
    viewsDefinition.properties[viewKey][ux_specification_types_1.SchemaTag.artifactType] = ux_specification_types_1.ArtifactType.Manifest;
    viewsDefinition.properties[viewKey][ux_specification_types_1.SchemaTag.key] = viewKey;
    viewsDefinition.properties[viewKey][ux_specification_types_1.SchemaTag.keys] = [{ name: ux_specification_types_1.SchemaKeyName.key, value: viewKey }];
}
/**
 * Adjusts the entity type if a different entity set is maintained for a view.
 *
 * @param {EntitySet} entitySet - actual entity set (AVT information)
 * @param view - the current view in manifest
 * @param {GenerateAppSchemaParameters} generateParameters - list of API input parameters
 * @returns the target entity type
 */
function getTargetEntityType(entitySet, view, generateParameters) {
    let targetEntityType = generateParameters.entityType;
    let viewEntitySet = entitySet;
    if (view['entitySet'] && view['entitySet'] !== entitySet.name) {
        viewEntitySet = generateParameters.serviceAVT?.entitySets.find((es) => {
            return es.name === view['entitySet'];
        });
        targetEntityType = viewEntitySet.entityType;
    }
    return targetEntityType;
}
/**
 * Adds view custom extensions - custom column and custom action definitions.
 *
 * @param commonInputParameters - list of input parameters as collected by the calling instance
 * @param generateParameters - list of API input parameters
 * @param visualization - visualization of the annotation
 * @param v4Page - the given page in manifest
 */
function addViewCustomExtensions(commonInputParameters, generateParameters, visualization, v4Page) {
    const sectionId = `${ux_specification_types_1.DefinitionName.LineItemsOfView}::${commonInputParameters.viewKey}`;
    const sectionIdPrefix = commonInputParameters.entitySet ? `/${commonInputParameters.entitySet}/` : '';
    const sectionIdInManifest = `${sectionIdPrefix}@${"com.sap.vocabularies.UI.v1.LineItem" /* UIAnnotationTerms.LineItem */}${visualization.split(ux_specification_types_1.Visualization.LineItem)[1]}`;
    const viewColumnDefinition = (0, common_1.parseSchemaDefinition)(ux_specification_types_1.DefinitionName.ViewCustomColumn, sectionId, commonInputParameters.appSchema);
    (0, common_1.addDefinitionRef)(viewColumnDefinition.properties.position, ux_specification_types_1.DefinitionName.ViewPosition, sectionId);
    (0, common_1.parseSchemaDefinition)(ux_specification_types_1.DefinitionName.ViewPosition, sectionId, commonInputParameters.appSchema);
    (0, utils_1.addCustomColumnDefinition)(commonInputParameters.appSchema, v4Page, generateParameters.logger, `${ux_specification_types_1.DefinitionName.ViewCustomColumn}<${sectionId}>`, sectionId, sectionIdInManifest);
    (0, utils_1.addFragmentEnumForAnchor)(commonInputParameters.appSchema, sectionId, v4Page, `${ux_specification_types_1.DefinitionName.ViewPosition}<${sectionId}>`, sectionIdInManifest);
    // Remove generic position
    if (commonInputParameters.appSchema.definitions.Position) {
        delete commonInputParameters.appSchema.definitions.Position;
    }
    // Table toolbar actions with custom actions
    const schemaIdForToolbarActions = `${ux_specification_types_1.DefinitionName.Actions}<${sectionId}>`;
    const customActionDefinitionKey = `${ux_specification_types_1.DefinitionName.ViewCustomAction}<${sectionId}>`;
    (0, utils_1.addCustomActionDefinition)(commonInputParameters.appSchema, v4Page, generateParameters.logger, customActionDefinitionKey, schemaIdForToolbarActions, sectionIdInManifest);
    // Anchor selection
    (0, common_1.parseSchemaDefinition)(ux_specification_types_1.DefinitionName.ViewCustomActionPosition, sectionId, commonInputParameters.appSchema);
    const customActionPositionDefinitionKey = `${ux_specification_types_1.DefinitionName.ViewCustomActionPosition}<${sectionId}>`;
    const customActionDefinition = commonInputParameters.appSchema.definitions[customActionDefinitionKey];
    customActionDefinition.properties.position.$ref =
        `${common_1.DEFINITION_LINK_PREFIX}${customActionPositionDefinitionKey}`;
    (0, utils_1.addEnumForActionAnchor)(commonInputParameters.appSchema, schemaIdForToolbarActions, customActionPositionDefinitionKey);
}
/**
 * Adds definition parts to a LR View (LineItem/Chart).
 *
 * @param visualization - visualization of the annotation
 * @param viewsDefinition - the views definition in app schema (MultiTableModeV4)
 * @param commonInputParameters - list of input parameters as collected by the calling instance
 * @param generateParameters - list of API input parameters
 * @param v4Page - the given page in manifest
 * @param uiAnnotations - UI annotations of the given entityType
 * @param view - the given view
 */
function addLRViewParts(visualization, viewsDefinition, commonInputParameters, generateParameters, v4Page, uiAnnotations, view) {
    if (visualization?.indexOf(ux_specification_types_1.Visualization.LineItem) > -1) {
        //Add Line item view
        addViewLineItems(commonInputParameters, viewsDefinition, visualization, commonInputParameters.targetAnnotation, generateParameters);
        addViewCustomExtensions(commonInputParameters, generateParameters, visualization, v4Page);
    }
    else if (visualization?.indexOf('Chart') > -1) {
        //Add Chart view
        addViewChart(commonInputParameters, uiAnnotations, commonInputParameters.appSchema, viewsDefinition, commonInputParameters.viewKey, commonInputParameters.title);
    }
    else if (view['template']) {
        const titleOnHover = view['label'] || `Custom View (key: ${commonInputParameters.viewKey})`;
        viewsDefinition.properties[commonInputParameters.viewKey] = {
            description: commonInputParameters.title || titleOnHover,
            title: titleOnHover,
            // Default view - use table view reference as default
            $ref: `${common_1.DEFINITION_LINK_PREFIX}${ux_specification_types_1.DefinitionName.TableViewExtension}`
        };
    }
    else {
        const titleOnHover = `View (key: ${commonInputParameters.viewKey})`;
        viewsDefinition.properties[commonInputParameters.viewKey] = {
            description: commonInputParameters.title || titleOnHover,
            title: titleOnHover,
            // Default view - use table view reference as default
            $ref: `${common_1.DEFINITION_LINK_PREFIX}${ux_specification_types_1.DefinitionName.LRTableView}`
        };
    }
}
/**
 * Add list report views to the app-specific schema.
 *
 * @param appSchema - app-specific JSON schema
 * @param viewsPaths - views' paths' section in the manifest
 * @param generateParameters - list of API input parameters
 * @param v4Page - the given page in manifest
 * @param tableDefinitionName - The name of the table definition in the schema
 */
function addLRViews(appSchema, viewsPaths, generateParameters, v4Page, tableDefinitionName) {
    const tableDefinition = appSchema.definitions[tableDefinitionName];
    tableDefinition.properties = {
        annotationPath: tableDefinition.properties.annotationPath,
        initialLoad: tableDefinition.properties.initialLoad,
        views: tableDefinition.properties.views
    };
    const viewsDefinition = appSchema.definitions.MultiTableModeV4;
    for (const view of viewsPaths) {
        if (!view[ux_specification_types_1.SchemaTag.key]) {
            continue;
        }
        let navPropName = undefined;
        const targetEntityType = getTargetEntityType(generateParameters.entitySet, view, generateParameters);
        const uiAnnotations = targetEntityType?.annotations.UI;
        const { visualization, targetAnnotation, namespace, title } = analyzeViewAnnotation(view?.[ux_specification_types_1.SchemaTag.annotationPath], uiAnnotations, generateParameters.serviceAVT, view[ux_specification_types_1.SchemaTag.key], undefined, generateParameters.logger);
        if (view['entitySet']) {
            navPropName = generateParameters.entityType.navigationProperties.find((np) => {
                return np.targetTypeName === namespace;
            })?.name;
        }
        const viewKey = (0, common_1.prepareRef)(view[ux_specification_types_1.SchemaTag.key]);
        const commonInputParameters = {
            viewKey,
            appSchema,
            targetAnnotation,
            navPropName,
            targetEntityType,
            title,
            entitySet: view['entitySet']
        };
        addLRViewParts(visualization, viewsDefinition, commonInputParameters, generateParameters, v4Page, uiAnnotations, view);
        addTagsToView(viewsDefinition, viewKey, namespace, view);
    }
}
/**
 * Adapts the table definition in schema.
 * Evaluates the path depending on if defaultTemplateAnnotationPath or Selection-/PresentationVariant is present.
 *
 * @param appSchema - the app-specific JSON schema
 * @param generateParameters - list of API input parameters
 * @param templateAnnotation - defaultTemplateAnnotationPath as registered in manifest
 * @param v4Page - the given page in manifest
 * @param alias - alias definition for the UI vocabulary
 * @param tableDefinitionName - The name of the table definition in the schema
 */
function adaptTableDefinition(appSchema, generateParameters, templateAnnotation, v4Page, alias, tableDefinitionName) {
    //here: tableDefinitionName = DefinitionName.Table
    const tableDefinition = appSchema.definitions[tableDefinitionName];
    const { visualization, targetAnnotation, namespace } = analyzeViewAnnotation(templateAnnotation, generateParameters.entityType?.annotations.UI, generateParameters.serviceAVT, undefined, ux_specification_types_1.Visualization.LineItem, generateParameters.logger);
    if (visualization) {
        const annotationTerm = visualization.split('.')[1];
        const annotationTermInSchema = `${ux_specification_types_1.DefinitionName.LineItems}OfSPV::${(0, common_1.prepareRef)(annotationTerm)}`;
        const spvTable = (appSchema.definitions[`${tableDefinitionName}SPV`] = JSON.parse(JSON.stringify(appSchema.definitions[tableDefinitionName])));
        delete spvTable[ux_specification_types_1.SchemaTag.isViewNode];
        (0, common_1.addDefinitionRef)(spvTable.properties.toolBar, ux_specification_types_1.DefinitionName.ToolBar, annotationTermInSchema);
        // Switch from generic column to specific definition
        spvTable[ux_specification_types_1.SchemaTag.annotationPath] = targetAnnotation;
        spvTable.properties.columns = {};
        (0, common_1.addDefinitionRef)(spvTable.properties.columns, annotationTermInSchema);
        delete tableDefinition.properties;
        (0, common_1.addDefinitionRef)(tableDefinition, `${tableDefinitionName}SPV`);
        tableDefinition[ux_specification_types_1.SchemaTag.annotationPath] = `/${namespace}/@${templateAnnotation}`;
        const lineItemAnnotation = generateParameters.entityType?.annotations.UI[annotationTerm];
        if (!lineItemAnnotation) {
            (0, extensionLogger_1.log)(generateParameters.logger, {
                severity: "error" /* LogSeverity.Error */,
                message: i18next_1.default.t('NOTARGET', { target: annotationTerm })
            });
        }
        const dataForLineItem = {
            isObjectPage: false,
            appSchema,
            lineItemAnnotation,
            entityType: generateParameters.entityType,
            oDataServiceAVT: generateParameters.serviceAVT,
            lineItemId: annotationTermInSchema
        };
        (0, utils_1.addLineItemsTypeToSchema)(dataForLineItem);
        const annotationTermQualifier = annotationTerm.split('#')?.[1];
        const sectionIdInManifest = annotationTermQualifier
            ? `@${"com.sap.vocabularies.UI.v1.LineItem" /* UIAnnotationTerms.LineItem */}#${annotationTermQualifier}`
            : `@${"com.sap.vocabularies.UI.v1.LineItem" /* UIAnnotationTerms.LineItem */}`;
        (0, utils_1.addCustomColumnDefinition)(appSchema, v4Page, generateParameters.logger, undefined, annotationTermInSchema, sectionIdInManifest);
        (0, utils_1.addFragmentEnumForAnchor)(appSchema, annotationTermInSchema, v4Page, undefined, sectionIdInManifest);
        // Table toolbar actions with custom actions
        const schemaIdForToolbarActions = `${ux_specification_types_1.DefinitionName.Actions}<${annotationTermInSchema}>`;
        const customColumnDefinitionName = (0, common_1.getCustomExtensionDefinitionName)(appSchema, annotationTermInSchema, ux_specification_types_1.DefinitionName.CustomTableAction);
        (0, utils_1.addCustomActionDefinition)(appSchema, v4Page, generateParameters.logger, (0, common_1.getDefinitionKey)(customColumnDefinitionName), schemaIdForToolbarActions, sectionIdInManifest);
        (0, utils_1.addEnumForActionAnchor)(appSchema, schemaIdForToolbarActions, ux_specification_types_1.DefinitionName.CustomActionPosition);
    }
    else {
        tableDefinition.properties.toolBar['$ref'] = `${common_1.DEFINITION_LINK_PREFIX}${ux_specification_types_1.DefinitionName.ToolBarLR}`;
        // Switch from generic column to specific definition
        (0, common_1.addDefinitionRef)(tableDefinition.properties.columns, ux_specification_types_1.DefinitionName.LineItems);
        const lineItemAnnotation = generateParameters.entityType?.annotations?.[alias]?.LineItem;
        if (!lineItemAnnotation && !v4Page.options?.settings?.views?.paths) {
            (0, extensionLogger_1.log)(generateParameters.logger, {
                severity: "error" /* LogSeverity.Error */,
                message: i18next_1.default.t('NOLINEITEMS')
            });
        }
        const dataForLineItem = {
            isObjectPage: false,
            appSchema,
            lineItemAnnotation,
            entityType: generateParameters.entityType,
            oDataServiceAVT: generateParameters.serviceAVT,
            lineItemId: ux_specification_types_1.DefinitionName.LineItems
        };
        (0, utils_1.addLineItemsTypeToSchema)(dataForLineItem);
        (0, utils_1.addCustomColumnDefinition)(appSchema, v4Page, generateParameters.logger);
        (0, utils_1.addFragmentEnumForAnchor)(appSchema, ux_specification_types_1.DefinitionName.LineItems, v4Page);
        if (lineItemAnnotation && !v4Page.options?.settings?.views?.paths) {
            tableDefinition[ux_specification_types_1.SchemaTag.annotationPath] = (0, common_1.createAnnotationPath)(generateParameters.entityType?.fullyQualifiedName, lineItemAnnotation.term, lineItemAnnotation.qualifier);
        }
        // Table toolbar actions with custom actions
        const schemaIdForActions = `${ux_specification_types_1.DefinitionName.Actions}<${(0, common_1.prepareRef)(ux_specification_types_1.DefinitionName.LineItems)}>`;
        (0, utils_1.addCustomActionDefinition)(appSchema, v4Page, generateParameters.logger, undefined, schemaIdForActions);
        (0, utils_1.addEnumForActionAnchor)(appSchema, schemaIdForActions, ux_specification_types_1.DefinitionName.CustomActionPosition);
    }
}
/**
 * Checks for the default annotation path to use for LR table.
 *
 * @param v4Page - actual page in the manifest
 * @param entityType - actual entity type (AVT information)
 * @param templateType - The type of template being used (e.g., ListReportObjectPageV4 or AnalyticalListPageV4)
 * @returns annotation term
 */
function getDefaultAnnotationPath(v4Page, entityType, templateType) {
    if (v4Page.options.settings?.views?.paths && templateType === ux_specification_types_1.TemplateType.ListReportObjectPageV4) {
        return;
    }
    if (v4Page.options.settings?.defaultTemplateAnnotationPath) {
        return v4Page.options.settings.defaultTemplateAnnotationPath;
    }
    if (templateType === ux_specification_types_1.TemplateType.ListReportObjectPageV4) {
        return (entityType?.annotations.UI?.SelectionPresentationVariant?.term ||
            entityType?.annotations.UI?.PresentationVariant?.term);
    }
}
/**
 * Add views to schema (LR or ALP).
 *
 * @param appSchema - app-specific JSON schema
 * @param v4Page - actual page in the manifest
 * @param generateParameters - list of API input parameters
 * @param alias - The alias of the OData annotations
 */
function addTableAndViews(appSchema, v4Page, generateParameters, alias) {
    const viewsPaths = v4Page.options?.settings?.views?.paths;
    const entityType = generateParameters.entityType;
    const defaultAnnotation = getDefaultAnnotationPath(v4Page, generateParameters.entityType, generateParameters.templateType);
    const tableDefinitionName = (0, utils_1.alignSchemaWithTemplateType)(appSchema, generateParameters);
    // Add filter bar
    addFilterBar(entityType, appSchema, v4Page, alias);
    if (generateParameters.templateType === ux_specification_types_1.TemplateType.ListReportObjectPageV4) {
        adaptTableDefinition(appSchema, generateParameters, defaultAnnotation, v4Page, alias, tableDefinitionName);
        if (viewsPaths) {
            delete appSchema.definitions['LineItems'];
            delete appSchema.definitions['ToolBar<LineItems>'];
            delete appSchema.definitions['Actions<LineItems>'];
            addLRViews(appSchema, viewsPaths, generateParameters, v4Page, tableDefinitionName);
        }
        else if (!v4Page.options?.settings?.views) {
            appSchema.definitions.MultiTableModeV4.properties = {};
        }
        appSchema.properties[ux_specification_types_1.PropertyName.chart][ux_specification_types_1.SchemaTag.hidden] = true;
    }
    else if (generateParameters.templateType === ux_specification_types_1.TemplateType.AnalyticalListPageV4) {
        addALPViews(appSchema, viewsPaths, generateParameters, defaultAnnotation, v4Page, tableDefinitionName);
        (0, utils_1.addFragmentEnumForAnchor)(appSchema, ux_specification_types_1.DefinitionName.LineItems, v4Page);
    }
}
/**
 * Adds header actions to schema (LR or ALP).
 *
 * @param appSchema - app-specific JSON schema
 * @param v4Page - actual page in the manifest
 * @param logger - Logger class for logging messages
 */
function addHeaderActions(appSchema, v4Page, logger) {
    // add header action definitions
    const headerActionsDefinitionKey = ux_specification_types_1.DefinitionName.HeaderActions;
    const headerActionsDefinition = appSchema.definitions[headerActionsDefinitionKey];
    headerActionsDefinition[ux_specification_types_1.SchemaTag.isViewNode] = true;
    headerActionsDefinition.description = 'Actions';
    headerActionsDefinition.properties = {};
    // add custom action definitions
    const customActionDefinitionKey = ux_specification_types_1.DefinitionName.CustomHeaderAction;
    const customActionDefinition = appSchema.definitions[customActionDefinitionKey];
    customActionDefinition[ux_specification_types_1.SchemaTag.isViewNode] = true;
    customActionDefinition.description = 'Custom Action';
    (0, utils_1.addHeaderFooterCustomActionDefinition)(appSchema, v4Page, logger, customActionDefinitionKey, headerActionsDefinitionKey);
    const facetKey = ux_specification_types_1.DefinitionName.CustomHeaderActionPosition;
    (0, common_1.parseSchemaDefinition)(facetKey, facetKey, appSchema, false);
    // Anchor selection
    customActionDefinition.properties.position.$ref = `${common_1.DEFINITION_LINK_PREFIX}${facetKey}`;
    (0, utils_1.addEnumForActionAnchor)(appSchema, headerActionsDefinitionKey, facetKey);
}
/**
 * Generates an app specific schema for the FE V4 ListReport from the generic schema.
 * Generic types are replaced by information from the app specific annotations.
 *
 * @param {GenerateAppSchemaParameters} generateParameters - list of API input parameters
 * @param genericSchema  - generic JSON schema of an object page
 * @param {string} templateName - allows to distinguish list report from ALP
 * @param {string} contextPath - entity set (AVT object) that is relevant for the given page
 * @returns {object} application-specific schema of the list report
 */
function generateListReportSchemaV4(generateParameters, genericSchema, templateName, contextPath) {
    const appSchema = JSON.parse(JSON.stringify(genericSchema));
    const entityType = generateParameters.entityType;
    const alias = generateParameters.serviceAVT && (0, common_1.findAlias)(ux_specification_types_1.UIVOCABULARY, generateParameters.serviceAVT);
    appSchema.properties[ux_specification_types_1.PropertyName.defaultTemplateAnnotationPath][ux_specification_types_1.SchemaTag.hidden] = true;
    //enum for annotation path as part of QuickVariantSelection
    (0, common_1.addEnumForSingleTabVariant)(entityType, appSchema, ux_specification_types_1.DefinitionName.AnnotationPathAsObject);
    if (generateParameters.manifest) {
        //Find page in targets
        const pages = generateParameters.manifest[ux_specification_types_1.ManifestSection.ui5].routing
            .targets;
        if (!pages) {
            (0, extensionLogger_1.log)(generateParameters.logger, {
                severity: "error" /* LogSeverity.Error */,
                message: i18next_1.default.t('NOPAGES', { appId: generateParameters.manifest['sap.app']['id'] }),
                location: {
                    path: ux_specification_types_1.MANIFESTPATH,
                    range: [ux_specification_types_1.ManifestSection.generic]
                }
            });
            return appSchema;
        }
        const v4Page = (0, utils_1.findPageV4)(pages, templateName, generateParameters.entitySet, contextPath);
        if (!v4Page) {
            return appSchema;
        }
        addHeaderActions(appSchema, v4Page, generateParameters.logger);
        addTableAndViews(appSchema, v4Page, generateParameters, alias);
    }
    delete appSchema.definitions.GenericColumns;
    delete appSchema.definitions.Action;
    (0, common_1.updatePropertyIndices)(appSchema, ROOT_PROPERTIES_ORDER);
    return appSchema;
}
//# sourceMappingURL=listReport.js.map