"use strict";
var __webpack_require__ = {};
(()=>{
    __webpack_require__.d = (exports1, definition)=>{
        for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
            enumerable: true,
            get: definition[key]
        });
    };
})();
(()=>{
    __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
})();
(()=>{
    __webpack_require__.r = (exports1)=>{
        if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
            value: 'Module'
        });
        Object.defineProperty(exports1, '__esModule', {
            value: true
        });
    };
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
    ReportGenerator: ()=>ReportGenerator,
    assertReportGenerationOptions: ()=>assertReportGenerationOptions,
    nullReportGenerator: ()=>nullReportGenerator
});
const external_node_fs_namespaceObject = require("node:fs");
const external_node_path_namespaceObject = require("node:path");
const common_namespaceObject = require("@midscene/shared/common");
const env_namespaceObject = require("@midscene/shared/env");
const utils_namespaceObject = require("@midscene/shared/utils");
const html_utils_js_namespaceObject = require("./dump/html-utils.js");
const screenshot_store_js_namespaceObject = require("./dump/screenshot-store.js");
const external_types_js_namespaceObject = require("./types.js");
const external_utils_js_namespaceObject = require("./utils.js");
function _define_property(obj, key, value) {
    if (key in obj) Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
    });
    else obj[key] = value;
    return obj;
}
const nullReportGenerator = {
    onExecutionUpdate: ()=>{},
    flush: async ()=>{},
    finalize: async ()=>void 0,
    getReportPath: ()=>void 0
};
function assertReportGenerationOptions(opts) {
    if (false === opts.generateReport && true === opts.persistExecutionDump) throw new Error('persistExecutionDump cannot be true when generateReport is false');
}
class ReportGenerator {
    static create(reportFileName, opts) {
        assertReportGenerationOptions(opts);
        if (false === opts.generateReport) return nullReportGenerator;
        if (utils_namespaceObject.ifInBrowser) return nullReportGenerator;
        validateReportFileName(reportFileName);
        const reportRootDir = (0, common_namespaceObject.getMidsceneRunSubDir)('report');
        const outputDir = (0, external_node_path_namespaceObject.join)(reportRootDir, reportFileName);
        const reportPath = 'html-and-external-assets' === opts.outputFormat ? (0, external_node_path_namespaceObject.join)(outputDir, 'index.html') : (0, external_node_path_namespaceObject.join)(reportRootDir, ensureHtmlFileName(reportFileName));
        return new ReportGenerator({
            reportPath,
            screenshotMode: 'html-and-external-assets' === opts.outputFormat ? 'directory' : 'inline',
            persistExecutionDump: opts.persistExecutionDump,
            autoPrint: opts.autoPrintReportMsg
        });
    }
    onExecutionUpdate(execution, reportMeta, attributes) {
        this.lastExecution = execution;
        this.lastReportMeta = reportMeta;
        this.mergeReportAttributes(attributes);
        this.writeQueue = this.writeQueue.then(()=>{
            if (this.destroyed) return;
            this.doWriteExecution(execution, reportMeta);
        });
    }
    async flush() {
        await this.writeQueue;
    }
    async finalize() {
        if (this.lastExecution && this.lastReportMeta) this.onExecutionUpdate(this.lastExecution, this.lastReportMeta);
        await this.flush();
        this.destroyed = true;
        if (!this.initialized) return;
        this.printReportPath('finalized');
        return this.reportPath;
    }
    getReportPath() {
        return this.reportPath;
    }
    printReportPath(verb) {
        if (!this.autoPrint || !this.reportPath) return;
        if (env_namespaceObject.globalConfigManager.getEnvConfigInBoolean(env_namespaceObject.MIDSCENE_REPORT_QUIET)) return;
        if ('directory' === this.screenshotMode) (0, utils_namespaceObject.logMsg)(`Midscene - report ${verb}: npx serve ${(0, external_node_path_namespaceObject.dirname)(this.reportPath)}`);
        else (0, utils_namespaceObject.logMsg)(`Midscene - report ${verb}: ${this.reportPath}`);
    }
    doWriteExecution(execution, reportMeta) {
        const singleDump = this.wrapAsReportDump(execution, reportMeta);
        if ('inline' === this.screenshotMode) this.writeInlineExecution(execution, singleDump);
        else this.writeDirectoryExecution(execution, singleDump);
        if (this.shouldPersistExecutionDump) this.persistExecutionDumpToFile(execution, singleDump);
        if (!this.firstWriteDone) {
            this.firstWriteDone = true;
            this.printReportPath('generated');
        }
    }
    mergeReportAttributes(attributes) {
        if (!attributes) return;
        for (const [key, value] of Object.entries(attributes))if (null != value) {
            if ('data-group-id' !== key) this.reportAttributes[key] = String(value);
        }
    }
    hydrateStateFromExistingReport() {
        if (!(0, external_node_fs_namespaceObject.existsSync)(this.reportPath)) return;
        this.initialized = true;
        if (!this.shouldPersistExecutionDump) return;
        const reportDir = (0, external_node_path_namespaceObject.dirname)(this.reportPath);
        const existingExecutionIndices = (0, external_node_fs_namespaceObject.readdirSync)(reportDir).map((name)=>/^(\d+)\.execution\.json$/.exec(name)?.[1]).filter((index)=>Boolean(index)).map((index)=>Number.parseInt(index, 10)).filter((index)=>Number.isFinite(index));
        if (existingExecutionIndices.length > 0) this.executionLogIndex = Math.max(...existingExecutionIndices);
    }
    getDumpScriptAttributes() {
        return {
            'data-group-id': this.reportStreamId,
            ...this.reportAttributes
        };
    }
    wrapAsReportDump(execution, reportMeta) {
        return new external_types_js_namespaceObject.ReportActionDump({
            sdkVersion: reportMeta.sdkVersion,
            groupName: reportMeta.groupName,
            groupDescription: reportMeta.groupDescription,
            modelBriefs: reportMeta.modelBriefs,
            deviceType: reportMeta.deviceType,
            executions: [
                execution
            ]
        });
    }
    writeInlineExecution(execution, singleDump) {
        const dir = (0, external_node_path_namespaceObject.dirname)(this.reportPath);
        if (!(0, external_node_fs_namespaceObject.existsSync)(dir)) (0, external_node_fs_namespaceObject.mkdirSync)(dir, {
            recursive: true
        });
        if (!this.initialized) {
            (0, external_node_fs_namespaceObject.writeFileSync)(this.reportPath, (0, external_utils_js_namespaceObject.getReportTpl)());
            this.initialized = true;
        }
        for (const screenshot of execution.collectScreenshots())this.screenshotStore.persist(screenshot);
        const serialized = singleDump.serialize();
        (0, external_utils_js_namespaceObject.appendFileSync)(this.reportPath, `\n${(0, html_utils_js_namespaceObject.generateDumpScriptTag)(serialized, this.getDumpScriptAttributes())}`);
    }
    writeDirectoryExecution(execution, singleDump) {
        const dir = (0, external_node_path_namespaceObject.dirname)(this.reportPath);
        if (!(0, external_node_fs_namespaceObject.existsSync)(dir)) (0, external_node_fs_namespaceObject.mkdirSync)(dir, {
            recursive: true
        });
        for (const screenshot of execution.collectScreenshots())this.screenshotStore.persist(screenshot);
        const serialized = singleDump.serialize();
        if (!this.initialized) {
            (0, external_node_fs_namespaceObject.writeFileSync)(this.reportPath, `${(0, external_utils_js_namespaceObject.getReportTpl)()}${(0, html_utils_js_namespaceObject.getBaseUrlFixScript)()}`);
            this.initialized = true;
        }
        (0, external_utils_js_namespaceObject.appendFileSync)(this.reportPath, `\n${(0, html_utils_js_namespaceObject.generateDumpScriptTag)(serialized, this.getDumpScriptAttributes())}`);
    }
    getExecutionLogKey(execution) {
        if (!execution.id) throw new Error('ReportGenerator: execution.id is required for persisting execution dumps');
        return `id:${execution.id}`;
    }
    persistExecutionDumpToFile(execution, singleDump) {
        const dir = (0, external_node_path_namespaceObject.dirname)(this.reportPath);
        if (!(0, external_node_fs_namespaceObject.existsSync)(dir)) (0, external_node_fs_namespaceObject.mkdirSync)(dir, {
            recursive: true
        });
        const executionLogKey = this.getExecutionLogKey(execution);
        let fileIndex = this.executionLogFileIndexByExecutionKey.get(executionLogKey);
        if (!fileIndex) {
            this.executionLogIndex += 1;
            fileIndex = this.executionLogIndex;
            this.executionLogFileIndexByExecutionKey.set(executionLogKey, fileIndex);
        }
        const fileName = `${fileIndex}.execution.json`;
        const filePath = (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.reportPath), fileName);
        (0, external_node_fs_namespaceObject.writeFileSync)(filePath, singleDump.serialize(2), 'utf-8');
    }
    constructor(options){
        _define_property(this, "reportPath", void 0);
        _define_property(this, "screenshotMode", void 0);
        _define_property(this, "shouldPersistExecutionDump", void 0);
        _define_property(this, "autoPrint", void 0);
        _define_property(this, "firstWriteDone", false);
        _define_property(this, "executionLogIndex", 0);
        _define_property(this, "executionLogFileIndexByExecutionKey", new Map());
        _define_property(this, "reportStreamId", void 0);
        _define_property(this, "screenshotStore", void 0);
        _define_property(this, "initialized", false);
        _define_property(this, "lastExecution", void 0);
        _define_property(this, "lastReportMeta", void 0);
        _define_property(this, "reportAttributes", {});
        _define_property(this, "writeQueue", Promise.resolve());
        _define_property(this, "destroyed", false);
        this.reportPath = options.reportPath;
        this.screenshotMode = options.screenshotMode;
        this.shouldPersistExecutionDump = options.persistExecutionDump ?? false;
        this.autoPrint = options.autoPrint ?? true;
        this.reportStreamId = (0, utils_namespaceObject.uuid)();
        this.screenshotStore = new screenshot_store_js_namespaceObject.ScreenshotStore({
            mode: 'inline' === this.screenshotMode ? 'inline' : 'directory',
            reportPath: this.reportPath,
            screenshotsDir: (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(this.reportPath), 'screenshots'),
            writeInlineImage: (id, base64)=>{
                (0, external_utils_js_namespaceObject.appendFileSync)(this.reportPath, `\n${(0, html_utils_js_namespaceObject.generateImageScriptTag)(id, base64)}`);
            },
            alsoWriteFileCopy: this.shouldPersistExecutionDump
        });
        this.hydrateStateFromExistingReport();
        this.printReportPath('will be generated at');
    }
}
function ensureHtmlFileName(reportFileName) {
    return reportFileName.endsWith('.html') ? reportFileName : `${reportFileName}.html`;
}
function validateReportFileName(reportFileName) {
    if (!reportFileName?.trim()) throw new Error('reportFileName must be a non-empty string');
    if (/[\\/]/.test(reportFileName)) throw new Error('reportFileName must not contain path separators (`/` or `\\\\`)');
    if (/[:*?"<>|]/.test(reportFileName)) throw new Error('reportFileName contains illegal filename characters: : * ? " < > |');
}
exports.ReportGenerator = __webpack_exports__.ReportGenerator;
exports.assertReportGenerationOptions = __webpack_exports__.assertReportGenerationOptions;
exports.nullReportGenerator = __webpack_exports__.nullReportGenerator;
for(var __rspack_i in __webpack_exports__)if (-1 === [
    "ReportGenerator",
    "assertReportGenerationOptions",
    "nullReportGenerator"
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
Object.defineProperty(exports, '__esModule', {
    value: true
});

//# sourceMappingURL=report-generator.js.map