"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SuiteFactory = void 0;
const CommonFunctions = __importStar(require("../../common-functions/common-functions"));
const Messages = __importStar(require("../../helpers/console-messages"));
const Models = __importStar(require("../../models/models"));
const feature_formatter_1 = require("./feature-formatter");
const uuid_1 = require("uuid");
class SuiteFactory {
    constructor(userProperies) {
        this.userProperties = userProperies;
        this.suite = this.initializeSuite();
    }
    async parseJsons(collectedJsons, providedFeatures) {
        const features = await Promise.all(collectedJsons.map(jsonFeature => {
            const gherkinFeature = this.getGherkinFeature(providedFeatures, jsonFeature.name);
            const feature = new feature_formatter_1.FeatureFormatter(gherkinFeature, jsonFeature).parseFeature();
            this.updateSuiteStadistics(feature);
            if (!feature.elements?.length) {
                console.log(Messages.featureRemoved(feature.name));
                return null;
            }
            return feature;
        }));
        this.suite.features = features.flatMap(feature => feature ? [feature] : []);
        this.updateSuiteProperties();
        this.suite.results.overview.result = [...new Map(this.suite.results.overview.result.map(item => [item.status, item])).values()];
        this.suite.results.overview.resultStatusesJoined = this.suite.results.overview.result.map((value) => value.status.toString()).sort().join(';');
        if (this.userProperties.saveEnrichedJSON) {
            await this.saveEnrichedJson();
        }
        return this.suite;
    }
    updateSuiteProperties() {
        this.suite.features = this.suite.features.sort((firstFeature, secondFeature) => (firstFeature.id > secondFeature.id ? 1 : -1));
        this.addMissingMetadataToFeatures();
        this.suite.results.overview.durationHHMMSS = CommonFunctions.convertTimeFromNanoSecondsToHHMMSS(this.suite.results.overview.duration);
        this.suite.metadata = CommonFunctions.isMetadata(this.userProperties.reportMetadata) ? this.userProperties.reportMetadata : [];
        this.suite.features = this.setUniqueIdForEachFeature(this.suite.features);
    }
    async saveEnrichedJson() {
        await CommonFunctions.saveJsonFile(this.userProperties.reportPath, 'enriched-output.json', this.suite);
    }
    getGherkinFeature(providedFeatures, jsonFeatureName) {
        return providedFeatures?.length ? providedFeatures.filter(document => document.feature?.name === jsonFeatureName)[0]?.feature : null;
    }
    updateSuiteStadistics(feature) {
        const overview = feature.results.overview;
        this.suite.results.overview.duration += overview.duration;
        this.suite.results.features.passed += overview.result.filter(result => result.status === Models.Status.passed).length === overview.result.length && overview.result.length ? 1 : 0;
        this.suite.results.features.failed += overview.result.filter(result => result.status === Models.Status.failed).length === overview.result.length && overview.result.length ? 1 : 0;
        this.suite.results.features.pending += overview.result.filter(result => result.status === Models.Status.pending).length === overview.result.length && overview.result.length ? 1 : 0;
        this.suite.results.features.skipped += overview.result.filter(result => result.status === Models.Status.skipped).length === overview.result.length && overview.result.length ? 1 : 0;
        this.suite.results.features.ambiguous += overview.result.filter(result => result.status === Models.Status.ambiguous).length === overview.result.length && overview.result.length ? 1 : 0;
        this.suite.results.features.undefined += overview.result.filter(result => result.status === Models.Status.undefined).length === overview.result.length && overview.result.length ? 1 : 0;
        this.suite.results.features.various += Number([...new Set(overview.result)].length > 1);
        this.suite.results.features.total++;
        this.suite.results.scenarios = CommonFunctions.updateResultsAndPercentages(this.suite.results.scenarios, feature.results.scenarios);
        this.suite.results.steps = CommonFunctions.updateResultsAndPercentages(this.suite.results.steps, feature.results.steps);
        this.suite.results.features = CommonFunctions.updatePercentages(this.suite.results.features);
        this.suite.results.overview.result.push(...feature.results.overview.result);
    }
    initializeSuite() {
        const suite = {};
        suite.results = Models.reportResultsInitializer();
        suite.metadata = [];
        suite.metadataTitle = this.userProperties.reportMetadataTitle;
        suite.reportTitle = this.userProperties.reportTitle;
        return suite;
    }
    setUniqueIdForEachFeature(features) {
        const seen = new Set();
        const modifiedFeatures = features.map(feature => {
            if (seen.size === seen.add(feature.id).size) {
                feature.id += (0, uuid_1.v4)();
            }
            return feature;
        });
        return modifiedFeatures;
    }
    addMissingMetadataToFeatures() {
        const allMetadata = [];
        this.suite.features.forEach(feature => {
            if (feature.metadata?.length) {
                feature.metadata.forEach(metadataElement => {
                    if (!allMetadata.filter(metadataObject => metadataObject.name === metadataElement.name).length) {
                        allMetadata.push(metadataElement);
                    }
                });
            }
        });
        this.suite.results.overview.metadata = allMetadata;
        this.suite.features.forEach(feature => {
            allMetadata.forEach(metadataElement => {
                const featureMetadataName = feature.metadata?.filter(featureMetadataElement => featureMetadataElement.name === metadataElement.name);
                if (!featureMetadataName?.length) {
                    feature.metadata.push({ name: metadataElement.name, value: '' });
                }
            });
        });
    }
}
exports.SuiteFactory = SuiteFactory;
//# sourceMappingURL=suite-formatter.js.map