"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.attach = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const debug_1 = __importDefault(require("debug"));
const consoleLogsCollection_1 = require("./consoleLogsCollection");
const utils_1 = require("./utils");
const assortedHooks_1 = require("./assortedHooks");
const screenshotCollection_1 = require("./hooks/screenshotCollection");
const step_metadata_collection_1 = require("./hooks/step-metadata-collection");
const TestContext_1 = require("./TestContext");
const PuppeteerPageHooker_1 = require("./PuppeteerPageHooker");
const consts_1 = require("./consts");
const stacktraceHook_1 = require("./stacktraceHook");
const persist_1 = require("./persist");
const networkLogs_1 = require("./networkLogs");
const userSettings_1 = require("./userSettings/userSettings");
const loggerDebug = debug_1.default('root-cause:debug');
function getDefaultActiveFeatures() {
    return userSettings_1.resolveSettings({ features: {} }).features;
}
async function attach({ page, startTestParams, activeFeatures }, dateConstructor = Date) {
    const resolvedActiveFeatures = activeFeatures || getDefaultActiveFeatures();
    const callSite = utils_1.getSelfCallSiteFromStacktrace();
    const defaultTestName = dateConstructor.now().toString();
    const defaultStartTestParams = {
        runId: consts_1.FALLBACK_RUN_ID,
        fullName: `fullName ${defaultTestName}`,
        description: defaultTestName,
        fullSuitePath: (callSite === null || callSite === void 0 ? void 0 : callSite.getFileName()) || 'pseudo fullSuitePath',
        projectRoot: process.cwd(),
    };
    const resolvedStartTestParams = Object.assign(defaultStartTestParams, startTestParams !== null && startTestParams !== void 0 ? startTestParams : {});
    const resultsDirFullPath = utils_1.testResultDirFromStartParams(resolvedStartTestParams);
    await fs_extra_1.default.mkdirp(resultsDirFullPath);
    const context = new TestContext_1.TestContext(resultsDirFullPath, resolvedStartTestParams.description, resolvedStartTestParams.fullName, resolvedStartTestParams.fullSuitePath, resolvedActiveFeatures, dateConstructor);
    const instrumentor = new PuppeteerPageHooker_1.PuppeteerPageHooker(context, page);
    const hookedPage = instrumentor.wrapWithProxy(page);
    instrumentor.registerBeforeAllHook(assortedHooks_1.testSystemInfoHook);
    if (resolvedActiveFeatures.console) {
        instrumentor.registerBeforeAllHook(consoleLogsCollection_1.logsBeforeAllHook);
        instrumentor.registerAfterAllHook(consoleLogsCollection_1.logsAfterAllHook);
        instrumentor.registerBeforeHook(consoleLogsCollection_1.logsBeforeEachHook);
        instrumentor.registerAfterHook(consoleLogsCollection_1.logsAfterEachHook);
    }
    if (resolvedActiveFeatures.networkLogs) {
        instrumentor.registerBeforeAllHook(networkLogs_1.networkLogsBeforeAllHook);
    }
    if (!consts_1.IS_NODE_10) {
        instrumentor.registerBeforeHook(stacktraceHook_1.stacktraceHook);
    }
    instrumentor.registerAfterHook(assortedHooks_1.errorInStepHook);
    instrumentor.registerAfterHook(step_metadata_collection_1.puppeteerMetadata);
    instrumentor.registerBeforeHook(async (testContext, fnName, proxyContext) => {
        loggerDebug(`>>${proxyContext.constructor.name}>>${fnName}`);
    });
    if (resolvedActiveFeatures === null || resolvedActiveFeatures === void 0 ? void 0 : resolvedActiveFeatures.screenshots) {
        instrumentor.registerBeforeHook(screenshotCollection_1.puppeteerScreenshot);
    }
    if (resolvedActiveFeatures.networkLogs) {
        instrumentor.registerAfterAllHook(networkLogs_1.networkLogsAfterAllHook);
    }
    instrumentor.registerAfterAllHook(assortedHooks_1.testEndHook);
    await instrumentor.start();
    async function endTest(endStatus) {
        await instrumentor.end(endStatus);
    }
    function pauseStepsRecording() {
        instrumentor.pause();
    }
    function resumeStepsRecording() {
        instrumentor.resume();
    }
    function reportAssertion(assertion) {
        context.addAssertionStep({
            ...assertion,
        });
    }
    return {
        page: hookedPage,
        endTest,
        persist: (resultLabels) => persist_1.persist(resolvedStartTestParams === null || resolvedStartTestParams === void 0 ? void 0 : resolvedStartTestParams.runId, {
            projectRoot: resolvedStartTestParams === null || resolvedStartTestParams === void 0 ? void 0 : resolvedStartTestParams.projectRoot,
            resultLabel: resultLabels,
        }),
        pauseStepsRecording,
        resumeStepsRecording,
        reportAssertion,
    };
}
exports.attach = attach;
