"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const mongoose = require("mongoose");
class MongooseQueries {
    constructor(models) {
        // this.config = config;
        // this.mongooseConnection = mongooseConnection;
        this.models = models;
    }
    //   /**
    //    * Get report by id
    //    */
    //   public async getReportById(reportId: any): Promise<ExtendedReport> {
    //     const report: ExtendedReport = await this._getReportById(reportId);
    //     return report;
    //   }
    //   /**
    //    * Get all the reports of the database ordered
    //    */
    //   public async getAllTheElementsOrderedAndFiltered(
    //     orderValue: string,
    //     orderDirection: number,
    //     filterValue: string,
    //   ): Promise<ExtendedReport[]> {
    //     await this.mongooseConnection._connectToDatabase();
    //     await this.mongooseConnection._initializeCollections();
    //     const results = await this._getAllTheElementsOrderedAndFiltered(orderValue, orderDirection, filterValue);
    //     await this.mongooseConnection.disconnectFromDatabase();
    //     return results;
    //   }
    //   /**
    //    * Get all the reports of the database
    //    */
    //   public async getAllTheElements(): Promise<any> {
    //     return this.mongooseConnection
    //       ._connectToDatabase()
    //       .then(() => this.mongooseConnection._initializeCollections())
    //       .then(() => this._getAllTheElements())
    //       .then((report) => {
    //         this.mongooseConnection.disconnectFromDatabase();
    //         return report;
    //       });
    //   }
    //   /**
    //    * Get all the elements of a mongoDb database
    //    * @private
    //    */
    //   public async _getAllTheElements(): Promise<any> {
    //     return this.mongooseConnection.collections.reports.find().toArray();
    //   }
    /**
     * Get all the elements from mongodb database with features stored in another document
     *
     * @param {searchValue} value that is going to be searched in the name of the report.
     * if the value of the search is feature:some_text, then the database is going filtered by the reports with features with name, some_text
     * if the value of the search is scenario:some_text, then the database is going filtered by the reports with scenarios with name some_text
     * if the value of the search is step:some_text, then the database is going filtered by the reports with steps with name some_text
     * @private
     */
    async getAllTheElementsOrderedAndFiltered(orderValue, orderDirection, filterValue) {
        const sortObj = {};
        let ids = [];
        if (orderValue === 'results.overview.executionDate') {
            sortObj[orderValue] = orderDirection;
        }
        else {
            sortObj['results.overview.name'] = 1;
        }
        filterValue =
            filterValue !== ''
                ? filterValue
                    .replace(/[-[\]{}()*+?.,\\/^$|#\s]/g, '\\$&')
                : 'undefined';
        if (typeof filterValue !== 'undefined' && filterValue.includes('feature:')) {
            ids = (await this.models.featureModel.find({ name: { $regex: `${filterValue.replace('feature:', '')}` } }, { reportId: 1 }))
                .map(element => element.reportId);
        }
        else if (typeof filterValue !== 'undefined' && filterValue.includes('scenario:')) {
            const featureIds = (await this.models.scenarioModel.find({ name: { $regex: `${filterValue.replace('scenario:', '')}` } }, { featureId: 1 }))
                .map(element => element.featureId);
            ids = (await this.models.featureModel.find({ _id: featureIds })).map(element => element.reportId);
        }
        else if (typeof filterValue !== 'undefined' && filterValue.includes('step:')) {
            const scenariosId = (await this.models.stepModel.find({ name: { $regex: filterValue.replace('step:', '') } }, { scenarioId: 1 }))
                .map(element => element.scenarioId);
            const featuresIds = (await this.models.scenarioModel.find({ _id: scenariosId }, { featureId: 1 }))
                .map(element => element.featureId);
            ids = (await this.models.featureModel.find({ _id: featuresIds })).map(element => element.reportId);
        }
        else {
            ids = (await this.models.reportModel.find()).map(element => element._id);
        }
        return Promise.all(ids.map(objectId => this.getReportById(objectId)));
    }
    /**
     * Get one element from mongodb database by id
     *
     * @param {object} options JSON object with the options
     * @private
     */
    async getReportById(id) {
        const oId = typeof id === 'string' ? new mongoose.Types.ObjectId(id) : id;
        const report = (await this.models.reportModel.findById({ _id: oId })
            .populate({ options: { sort: { '_id': 1 } }, path: 'features',
            populate: { options: { sort: { '_id': 1 } }, path: 'elements',
                populate: { options: { sort: { '_id': 1 } }, path: 'steps', select: '-_id' }, select: '-_id' }, select: '-_id' }))?.toJSON();
        report.features = report.features.map(feature => {
            delete feature.reportId;
            feature.elements = feature.elements.map(scenario => {
                delete scenario.featureId;
                if (scenario?.before?.steps?.length > 0) {
                    scenario.before.steps = scenario.before.steps.map(step => this.removeFieldsFromStep(step));
                }
                if (scenario?.after?.steps?.length > 0) {
                    scenario.after.steps = scenario.after.steps.map(step => this.removeFieldsFromStep(step));
                }
                if (scenario?.steps && scenario?.steps.length > 0) {
                    scenario.steps = scenario.steps.map(step => {
                        delete step.scenarioId;
                        return step;
                    });
                }
                return scenario;
            });
            return feature;
        });
        delete report.id;
        delete report._id;
        return report;
    }
    removeFieldsFromStep(step) {
        delete step.scenarioId;
        delete step._id;
        return step;
    }
}
exports.default = MongooseQueries;
//# sourceMappingURL=mongoose-queries.js.map