'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var localsHelper = require('../../../utils/localsHelper.js');
var logger = require('../../../utils/logger.js');
var sessionHelper = require('../../../utils/sessionHelper.js');
var queryMappers = require('../../../utils/queryMappers.js');
var definitionUtils = require('../../../utils/definitionUtils.js');

/**
 * Streams the download for an Async repoort
 *
 * @param {({
 *   services: Services
 *   token: string
 *   tableId: string
 *   reportId: string
 *   id: string
 *   queryParams: Record<string, string | string[]>
 *   res: Response
 * })} args
 * @return {*}
 */
const streamDownloadAsyncData = async (args) => {
    const { token, services, tableId, reportId, id, queryParams, res } = args;
    return services.reportingService.downloadAsyncReport(token, reportId, id, tableId, queryParams, res);
};
/**
 * Streams the download for a sync report
 *
 * @param {({
 *   definition: components['schemas']['SingleVariantReportDefinition']
 *   services: Services
 *   token: string
 *   queryParams: Record<string, string | string[]>
 *   res: Response
 * })} args
 * @return {*}
 */
const streamDownloadSyncData = async (args) => {
    const { token, services, queryParams, definition, res } = args;
    const { variant } = definitionUtils.validateDefinition(definition);
    const { resourceName } = variant;
    return services.reportingService.downloadSyncReport(token, resourceName, queryParams, res);
};
/**
 * Downloads the report
 *
 * @param {{
 *   req: Request
 *   services: Services
 *   res: Response
 *   redirect: string
 * }} {
 *   req,
 *   services,
 *   res,
 *   redirect,
 * }
 */
const downloadReport = async ({ req, services, res }) => {
    const { reportId, id, tableId } = req.params;
    const { token, definitionsPath: dataProductDefinitionsPath } = localsHelper.default.getValues(res);
    const definition = await services.reportingService.getDefinition(token, reportId, id, dataProductDefinitionsPath);
    const queryParams = setQueryForDownload(req, definition, dataProductDefinitionsPath);
    logger.default.info(`Initiating streaming...`);
    if (!tableId) {
        await streamDownloadSyncData({
            definition,
            services,
            token,
            queryParams,
            res,
        });
    }
    else {
        await streamDownloadAsyncData({
            services,
            token,
            reportId,
            id,
            tableId,
            queryParams,
            res,
        });
    }
};
/**
 * Initialises the download config in the UI
 *
 * @param {Response} res
 * @param {Request} req
 * @param {ExtractedDefinitionData} definitionData
 * @param {LoadType} loadType
 * @param {ExtractedRequestData} [requestData]
 * @return {*}  {(DownloadActionParams | undefined)}
 */
const setUpDownload = (res, req) => {
    const { downloadingEnabled } = localsHelper.default.getValues(res);
    let downloadConfig;
    if (downloadingEnabled) {
        const { tableId, id, reportId } = req.params;
        const { csrfToken } = localsHelper.default.getValues(res);
        const { downloadActionEndpoint } = localsHelper.default.getRouteLocals(res);
        const downloadEnabledForReport = sessionHelper.getActiveJourneyValue(req, { id, reportId }, 'downloadEnabled');
        const formaction = tableId
            ? `${downloadActionEndpoint}${reportId}/${id}/tableId/${tableId}`
            : `${downloadActionEndpoint}${reportId}/${id}`;
        return {
            enabled: downloadingEnabled,
            formAction: formaction,
            canDownload: Boolean(downloadEnabledForReport),
            csrfToken,
        };
    }
    return downloadConfig;
};
/**
 * Sets the query for the download API request
 *
 * @param {string} currentReportSearch
 * @param {components['schemas']['SingleVariantReportDefinition']} definition
 * @return {*}
 */
const setQueryForDownload = (req, definition, dataProductDefinitionsPath) => {
    const { reportId, id, tableId } = req.params;
    const sessionKey = tableId ? { reportId, id, tableId } : { reportId, id };
    const currentReportSearch = sessionHelper.getActiveJourneyValue(req, sessionKey, 'currentReportSearch') || '';
    // Filters query
    const filtersQuery = queryMappers.qsToQueryObject(currentReportSearch, 'filters.');
    // Sort query
    let sortQuery = queryMappers.qsToQueryObject(currentReportSearch, 'sort');
    if (!sortQuery || Object.keys(sortQuery).length === 0) {
        // Fall back to default
        const defaultSortQueryString = sessionHelper.getActiveJourneyValue(req, sessionKey, 'defaultSortQueryString') || '';
        sortQuery = queryMappers.qsToQueryObject(defaultSortQueryString, 'sort');
    }
    // Columns
    const columnsQuery = queryMappers.qsToQueryObject(currentReportSearch, 'columns');
    const validColumnsQuery = setColumnsForDownload(columnsQuery, definition);
    return {
        ...filtersQuery,
        ...validColumnsQuery,
        ...sortQuery,
        ...(dataProductDefinitionsPath && { dataProductDefinitionsPath }),
    };
};
/**
 * Gets the columns/fields for the download request
 *
 * - Fields with fieldSource of 'specfield' should be discarded
 *
 * @param {Columns} columns
 * @param {ExtractedDefinitionData} definitionData
 * @return {*}
 */
const setColumnsForDownload = (query, definition) => {
    const fields = definitionUtils.getFields(definition);
    const { specification } = definition.variant;
    // Ensure sections heading are always included in download, if present
    const sections = specification?.sections || [];
    // master columns list
    const requestedColumns = [...new Set([...query['columns'], ...sections])];
    // Ensure only valid columns are part of download query
    const validColumns = requestedColumns.filter((fieldName) => {
        const field = definitionUtils.getField(fields, fieldName);
        return field && (field.fieldSource === 'specfield' || field.fieldSource === undefined);
    });
    return { columns: validColumns };
};
var DownloadUtils = {
    downloadReport,
    setUpDownload,
};

exports.default = DownloadUtils;
exports.downloadReport = downloadReport;
exports.setUpDownload = setUpDownload;
//# sourceMappingURL=utils.js.map
