"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const request_event_1 = __importDefault(require("../request-hooks/events/request-event"));
const names_1 = __importDefault(require("../request-hooks/events/names"));
const get_response_1 = __importDefault(require("../request-hooks/response-mock/get-response"));
const info_1 = require("../request-hooks/events/info");
const response_event_1 = __importDefault(require("../request-hooks/events/response-event"));
const request_is_match_rule_1 = __importDefault(require("../request-hooks/request-is-match-rule"));
class BaseRequestPipelineContext {
    constructor(requestId) {
        this.onResponseEventData = [];
        this.requestFilterRules = [];
        this.requestId = requestId;
        this.injectableUserScripts = [];
    }
    async _forEachRequestFilterRule(fn) {
        await Promise.all(this.requestFilterRules.map(fn));
    }
    setupMockIfNecessary(event, eventProvider) {
        const mock = eventProvider.getMock(event.id);
        if (mock && !this.mock)
            this.mock = mock;
    }
    setRequestOptions(eventFactory) {
        this.reqOpts = eventFactory.createRequestOptions();
    }
    getOnResponseEventData({ includeBody }) {
        return this.onResponseEventData.filter(eventData => eventData.opts.includeBody === includeBody);
    }
    async onRequestHookRequest(eventProvider, eventFactory) {
        const requestInfo = eventFactory.createRequestInfo();
        this.requestFilterRules = await eventProvider.getRequestFilterRules(requestInfo);
        await this._forEachRequestFilterRule(async (rule) => {
            const requestEvent = new request_event_1.default({
                requestFilterRule: rule,
                _requestInfo: requestInfo,
                reqOpts: this.reqOpts,
                setMockFn: eventProvider.setMock.bind(eventProvider),
            });
            await eventProvider.callRequestEventCallback(names_1.default.onRequest, rule, requestEvent);
            this.setupMockIfNecessary(requestEvent, eventProvider);
        });
    }
    async onRequestHookConfigureResponse(eventProvider, eventFactory) {
        await Promise.all(this.requestFilterRules.map(async (rule) => {
            const configureResponseEvent = eventFactory.createConfigureResponseEvent(rule);
            await eventProvider.callRequestEventCallback(names_1.default.onConfigureResponse, rule, configureResponseEvent);
            this.onResponseEventData.push({
                rule: configureResponseEvent.requestFilterRule,
                opts: configureResponseEvent.opts,
            });
        }));
    }
    async onRequestHookResponse(eventProvider, eventFactory, rule, opts) {
        const responseInfo = eventFactory.createResponseInfo();
        const preparedResponseInfo = new info_1.PreparedResponseInfo(responseInfo, opts);
        const responseEvent = new response_event_1.default(rule, preparedResponseInfo);
        await eventProvider.callRequestEventCallback(names_1.default.onResponse, rule, responseEvent);
        return responseEvent;
    }
    async getMockResponse() {
        this.mock.setRequestOptions(this.reqOpts);
        return (0, get_response_1.default)(this.mock);
    }
    async handleMockError(eventProvider) {
        const targetRule = this.requestFilterRules[0];
        await eventProvider.callRequestHookErrorHandler(targetRule, this.mock.error);
    }
    async prepareInjectableUserScripts(eventFactory, userScripts) {
        if (!userScripts.length)
            return;
        const requestInfo = eventFactory.createRequestInfo();
        const matchedUserScripts = await Promise.all(userScripts.map(async (userScript) => {
            if (await (0, request_is_match_rule_1.default)(userScript.page, requestInfo))
                return userScript;
            return void 0;
        }));
        const injectableUserScripts = matchedUserScripts
            .filter(userScript => !!userScript)
            .map(userScript => (userScript === null || userScript === void 0 ? void 0 : userScript.url) || '');
        if (injectableUserScripts)
            this.injectableUserScripts = injectableUserScripts;
    }
}
exports.default = BaseRequestPipelineContext;module.exports = exports.default;