'use strict';

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

var UserReports = require('../../../../types/UserReports.js');
var reportStoreService = require('../../../../services/reportStoreService.js');
var urlHelper = require('../../../../utils/urlHelper.js');
var logger = require('../../../../utils/logger.js');

class RequestedReportService extends reportStoreService.ReportStoreService {
    constructor(userDataStore) {
        super(userDataStore);
    }
    async addReport(userId, reportStateData) {
        const userConfig = await this.getState(userId);
        userConfig.requestedReports.unshift(reportStateData);
        await this.saveState(userId, userConfig);
    }
    async removeReport(id, userId) {
        const userConfig = await this.getState(userId);
        const index = this.findIndexByExecutionId(id, userConfig.requestedReports);
        userConfig.requestedReports.splice(index, 1);
        await this.saveState(userId, userConfig);
    }
    async getReportByExecutionId(id, userId) {
        const userConfig = await this.getState(userId);
        return userConfig.requestedReports.find((report) => report.executionId === id);
    }
    async getReportByTableId(id, userId) {
        const userConfig = await this.getState(userId);
        return userConfig.requestedReports.find((report) => report.tableId === id);
    }
    async getAllReports(userId) {
        const userConfig = await this.getState(userId);
        return userConfig.requestedReports;
    }
    async getAllReportsById(id, userId) {
        const userConfig = await this.getState(userId);
        return userConfig.requestedReports.filter((requested) => {
            return (requested.id && requested.id === id) || (requested.variantId && requested.variantId === id);
        });
    }
    async updateLastViewed(id, userId) {
        const userConfig = await this.getState(userId);
        const index = this.findIndexByExecutionId(id, userConfig.requestedReports);
        const report = userConfig.requestedReports[index];
        report.timestamp.lastViewed = new Date();
        userConfig.requestedReports[index] = report;
        await this.saveState(userId, userConfig);
    }
    async updateStatus(id, userId, status, errorMessage) {
        const userConfig = await this.getState(userId);
        const index = this.findIndexByExecutionId(id, userConfig.requestedReports);
        let report = userConfig.requestedReports[index];
        if (report)
            report = this.updateDataByStatus(report, status, errorMessage);
        userConfig.requestedReports[index] = report;
        await this.saveState(userId, userConfig);
    }
    async setToExpired(id, userId) {
        const userConfig = await this.getState(userId);
        const index = this.findIndexByExecutionId(id, userConfig.requestedReports);
        let report = userConfig.requestedReports[index];
        if (report) {
            report = {
                ...report,
                status: UserReports.RequestStatus.EXPIRED,
                timestamp: {
                    ...report.timestamp,
                    expired: new Date(),
                },
            };
            userConfig.requestedReports[index] = report;
            await this.saveState(userId, userConfig);
        }
    }
    /**
     * Removes old stale data from requested reports
     * - When a report is viewed it is given a lastViewed ts.
     * - If the requested data has a lastViewed ts and
     * - has no corresponding viewed entry
     * - then that requested data is stale and can be removed
     *
     * @param {string} userId
     * @param {StoredReportData[]} viewedReports
     * @memberof RequestedReportService
     */
    async cleanList(userId, viewedReports) {
        const userConfig = await this.getState(userId);
        const allRequested = userConfig.requestedReports;
        const viewedRequestedReports = allRequested.filter((requestedReport) => {
            return requestedReport.timestamp.lastViewed !== undefined;
        });
        let count = 0;
        await Promise.all(viewedRequestedReports.map(async (viewedRequestReport) => {
            const { executionId } = viewedRequestReport;
            const viewedReport = viewedReports.find((report) => {
                const { executionId: viewedExecutionId } = report;
                return viewedExecutionId && viewedExecutionId === executionId;
            });
            if (!viewedReport && executionId) {
                await this.removeReport(executionId, userId);
                count += 1;
            }
        }));
        if (count > 0)
            logger.default.info(`RequestedReports: Removed ${count} stale reports from list`);
    }
    setReportUrl(report) {
        const { tableId, url, dpdPathFromQuery, dataProductDefinitionsPath, type } = report;
        let pathname;
        let fullUrl;
        if (url && url.polling?.pathname) {
            let reportUrlArr = Array.from(new Array(2));
            reportUrlArr = url.polling.pathname.replace('/request-report', '/view-report/async').split('/');
            reportUrlArr[reportUrlArr.length - 2] = tableId;
            reportUrlArr[reportUrlArr.length - 1] = type;
            const reportUrl = reportUrlArr.join('/');
            const search = url.report?.search ? url.report.search : '';
            const dpdPath = dataProductDefinitionsPath && dpdPathFromQuery ? `${urlHelper.getDpdPathSuffix(dataProductDefinitionsPath)}` : '';
            const searchPath = search || dpdPath;
            pathname = `${reportUrl}${searchPath}`;
            fullUrl = `${url.origin}${pathname}`;
        }
        return {
            pathname,
            fullUrl,
        };
    }
    updateDataByStatus(report, status, errorMessage) {
        const ts = new Date();
        if (status)
            report.status = status;
        switch (status) {
            case UserReports.RequestStatus.FAILED:
                report.timestamp.failed = ts;
                if (errorMessage)
                    report.errorMessage = errorMessage;
                break;
            case UserReports.RequestStatus.EXPIRED:
                report.timestamp.expired = ts;
                break;
            case UserReports.RequestStatus.ABORTED:
                report.timestamp.aborted = ts;
                break;
            case UserReports.RequestStatus.FINISHED: {
                report.timestamp.completed = ts;
                if (report.url) {
                    report.url.report = {
                        ...report.url.report,
                        ...this.setReportUrl(report),
                    };
                }
                break;
            }
            case UserReports.RequestStatus.SUBMITTED:
                report.timestamp.requested = ts;
                break;
            case UserReports.RequestStatus.STARTED:
            case UserReports.RequestStatus.PICKED:
                break;
            default:
                report.timestamp.lastViewed = ts;
                break;
        }
        return report;
    }
}

exports.RequestedReportService = RequestedReportService;
exports.default = RequestedReportService;
//# sourceMappingURL=service.js.map
