'use strict';

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

var localsHelper = require('../utils/localsHelper.js');
var featureFlagService = require('../services/featureFlagService.js');
var featureFlagsHelper = require('../utils/featureFlagsHelper.js');
var setUpNunjucksFilters = require('../setUpNunjucksFilters.js');
var index = require('../routes/index.js');
var reportStoreHelper = require('../utils/reportStoreHelper.js');
var logger = require('../utils/logger.js');
var definitionUtils = require('../utils/definitionUtils.js');

/**
 * Middleware helper to populate all locals configuration
 * to enable DPR lib to operate correctly within a service.
 *
 * @param {Services} services
 * @param {string} layoutPath
 * @param {Environment} env
 * @param {DprConfig} [config]
 * @return {*}  {RequestHandler}
 */
const setupResources = (services, layoutPath, env, config) => {
    return async (req, res, next) => {
        populateValidationErrors(req, res);
        try {
            await setFeatures(res, services.featureFlagService);
            await populateDefinitions(services, req, res, config);
            await setLocalsFromServices(services, res);
            await populateRequestedReports(services, res);
            setUpDprPaths(res);
            setupRequestAwareNunjucks(env, res);
            setUpNunjucksFilters.default(env);
            return next();
        }
        catch (error) {
            return index.errorRequestHandler(layoutPath)(error, req, res, next);
        }
    };
};
const setupRequestAwareNunjucks = (env, res) => {
    env.addGlobal('getLocals', () => ({ locals: { ...res.locals, ...res.app.locals } }));
};
/**
 * Sets the feature flags to locals
 *
 * @param {Response} res
 * @param {FeatureFlagService} featureFlagService
 */
const setFeatures = async (res, featureFlagService) => {
    if (res.app.locals['featureFlags'] === undefined) {
        res.app.locals['featureFlags'] = {
            flags: {},
        };
    }
    const subject = featureFlagsHelper.getFeatureFlagEvaluationSubject(res);
    res.app.locals['featureFlags'].flags = await featureFlagService.evaluateBooleanFlags(featureFlagsHelper.FEATURE_FLAGS, subject);
    if (res.app.locals['featureFlags']) {
        logger.default.info(`FEATURE FLAGS: ${JSON.stringify(res.locals['downloadingEnabled'])}`);
    }
};
/**
 * Populates the validation errors
 *
 * @param {Request} req
 * @param {Response} res
 */
const populateValidationErrors = (req, res) => {
    const errors = req.flash(`DPR_ERRORS`);
    if (errors && errors[0]) {
        res.locals['validationErrors'] = JSON.parse(errors[0]);
    }
};
/**
 * Derives the definition path and sets the locals
 *
 * @param {Request} req
 * @param {Response} res
 * @param {DprConfig} [config]
 */
const deriveDefinitionsPath = (req, res, config) => {
    // Check definitions path from config
    const dpdPathFromConfig = config?.dataProductDefinitionsPath;
    res.locals['dpdPathFromConfig'] = !!dpdPathFromConfig;
    // Check definitions path from request
    const dpdPathFromQuery = definitionUtils.getDefinitionsPath(req.query) || null;
    const dpdPathFromBody = req.body?.dataProductDefinitionsPath;
    const definitionsPathFromQuery = dpdPathFromQuery || dpdPathFromBody;
    res.locals['dpdPathFromQuery'] = !!definitionsPathFromQuery;
    // Set the definitions path to locals
    // - incoming query overwrites config
    const activeDefinitionsPath = definitionsPathFromQuery || dpdPathFromConfig;
    if (activeDefinitionsPath) {
        res.locals['hasDefinitionPath'] = !!activeDefinitionsPath;
        res.locals['definitionsPath'] = activeDefinitionsPath;
        // TODO: check if this is needed - its possibly been superceded
        res.locals['pathSuffix'] = `?dataProductDefinitionsPath=${res.locals['definitionsPath']}`;
        logger.default.info(`DEFINITIONS PATH SET: ${JSON.stringify({
            definitionsPath: res.locals['definitionsPath'],
            dpdPathFromBody: res.locals['dpdPathFromBody'],
            dpdPathFromQuery: res.locals['dpdPathFromQuery'],
        })}`);
    }
};
/**
 * Popluates the definitions in to locals
 *
 * TODO: Optimization task:
 * - Evalulate how often/regularly this should be called?
 * - DPDS arent updated that often so its possible we could enable a timebased check of an hour?
 * - Concider the impact to embedded services + how soon a new DPD will be seen.
 * - Aim to reduce BE api calls
 *
 * @param {Services} services
 * @param {Request} req
 * @param {Response} res
 * @param {DprConfig} [config]
 */
const populateDefinitions = async (services, req, res, config) => {
    const { token, dprUser } = localsHelper.default.getValues(res);
    deriveDefinitionsPath(req, res, config);
    let selectedProductCollectionId;
    if (token) {
        selectedProductCollectionId = await services.productCollectionStoreService.getSelectedProductCollectionId(dprUser.id);
    }
    res.locals['definitions'] =
        (await Promise.all([
            services.reportingService.getDefinitions(token, res.locals['definitionsPath']),
            selectedProductCollectionId &&
                services.productCollectionService.getProductCollection(token, selectedProductCollectionId),
        ]).then(([defs, selectedProductCollection]) => {
            if (selectedProductCollection && selectedProductCollection) {
                const productIds = selectedProductCollection.products.map((product) => product.productId);
                return defs.filter((def) => productIds.includes(def.id));
            }
            return defs;
        })) ?? [];
    if (res.locals['definitions'] && res.locals['definitions'].length) {
        logger.default.info(`DEFINITIONS SET: ${res.locals['definitions'].length}`);
    }
};
/**
 * Sets active service config to locals
 *
 * TODO: Optimization task:
 * - set to res.app.locals instead of locals as this is set once at bootstrapping
 * - if set, dont set again
 *
 * @param {Services} services
 * @param {Response} res
 */
const setLocalsFromServices = async (services, res) => {
    const { dprUser } = localsHelper.default.getValues(res);
    if (dprUser.id) {
        res.locals['downloadingEnabled'] = services.downloadPermissionService.enabled;
        res.locals['bookmarkingEnabled'] = services.bookmarkService.enabled;
        res.locals['collectionsEnabled'] = services.productCollectionService.enabled;
        res.locals['requestMissingEnabled'] = services.missingReportService.enabled;
        // If saveDefaultsEnabled is turned off by feature flag, overwrite all other privileges,
        // otherwise let the defaultFilterValuesService decide.
        const saveDefaultsEnabledFlag = featureFlagService.isBooleanFlagEnabledOrMissing('saveDefaultsEnabled', res.app);
        res.locals['saveDefaultsEnabled'] = saveDefaultsEnabledFlag ? services.defaultFilterValuesService.enabled : false;
        logger.default.info(`ENABLED SERVICES: ${JSON.stringify({
            downloadingEnabled: res.locals['downloadingEnabled'],
            bookmarkingEnabled: res.locals['bookmarkingEnabled'],
            collectionsEnabled: res.locals['collectionsEnabled'],
            requestMissingEnabled: res.locals['requestMissingEnabled'],
            saveDefaultsEnabled: res.locals['saveDefaultsEnabled'],
        })}`);
    }
};
/**
 * Populates the requested reports to locals
 *
 * @param {Services} services
 * @param {Response} res
 */
const populateRequestedReports = async (services, res) => {
    const { dprUser } = localsHelper.default.getValues(res);
    if (dprUser.id) {
        const { requestedReports, recentlyViewedReports } = await reportStoreHelper.getAllMyReports(res, services, dprUser.id);
        res.locals['requestedReports'] = requestedReports;
        res.locals['recentlyViewedReports'] = recentlyViewedReports;
        if (res.locals['bookmarkingEnabled']) {
            res.locals['bookmarks'] = await reportStoreHelper.getAllMyBookmarks(res, services, dprUser.id);
        }
    }
};
/**
 * Initialises the DPR paths to locals
 *
 * @param {Response} res
 */
const setUpDprPaths = (res) => {
    res.app.locals.dprPaths ??= {
        bookmarkActionEndpoint: '/dpr/my-reports/bookmarks',
        downloadActionEndpoint: '/dpr/download-report/',
        productCollectionEndpoint: '/dpr/product-collection/selected',
        bookmarkListPath: '/dpr/my-reports/bookmarks',
        requestedListPath: '/dpr/my-reports/requested-reports',
        recentlyViewedListPath: '/dpr/my-reports/recently-viewed',
        reportsCatalogue: '/dpr/report-catalogue',
        userReportsList: '/dpr/my-reports',
        requestReportPath: '/dpr/request-report',
        viewReportPath: '/dpr/view-report',
        dprHomepage: '/dpr',
    };
};

exports.default = setupResources;
exports.setupResources = setupResources;
//# sourceMappingURL=setUpDprResources.js.map
