"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var DefaultBrowserEmulator_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultBrowserEngine = void 0;
const IUnblockedPlugin_1 = require("@unblocked-web/specifications/plugin/IUnblockedPlugin");
const Logger_1 = require("@ulixee/commons/lib/Logger");
const Viewports_1 = require("./lib/Viewports");
const BrowserEngine_1 = require("./lib/BrowserEngine");
const setWorkerDomOverrides_1 = require("./lib/setWorkerDomOverrides");
const setPageDomOverrides_1 = require("./lib/setPageDomOverrides");
const setUserAgent_1 = require("./lib/helpers/setUserAgent");
const setScreensize_1 = require("./lib/helpers/setScreensize");
const setTimezone_1 = require("./lib/helpers/setTimezone");
const setLocale_1 = require("./lib/helpers/setLocale");
const setActiveAndFocused_1 = require("./lib/helpers/setActiveAndFocused");
const selectUserAgentOption_1 = require("./lib/helpers/selectUserAgentOption");
const modifyHeaders_1 = require("./lib/helpers/modifyHeaders");
const configureSessionDns_1 = require("./lib/helpers/configureSessionDns");
const configureSessionTcp_1 = require("./lib/helpers/configureSessionTcp");
const configureSessionTls_1 = require("./lib/helpers/configureSessionTls");
const DataLoader_1 = require("./lib/DataLoader");
const selectBrowserEngineOption_1 = require("./lib/helpers/selectBrowserEngineOption");
const setGeolocation_1 = require("./lib/helpers/setGeolocation");
const configureBrowserLaunchArgs_1 = require("./lib/helpers/configureBrowserLaunchArgs");
const loadDomOverrides_1 = require("./lib/loadDomOverrides");
const configureDeviceProfile_1 = require("./lib/helpers/configureDeviceProfile");
const configureHttp2Session_1 = require("./lib/helpers/configureHttp2Session");
const lookupPublicIp_1 = require("./lib/helpers/lookupPublicIp");
const UserAgentOptions_1 = require("./lib/UserAgentOptions");
const BrowserEngineOptions_1 = require("./lib/BrowserEngineOptions");
// Configuration to rotate out the default browser id. Used for testing different browsers via cli
const defaultBrowserId = process.env.ULX_DEFAULT_BROWSER_ID ?? process.env.UBK_DEFAULT_BROWSER_ID;
const dataLoader = new DataLoader_1.default();
const browserEngineOptions = new BrowserEngineOptions_1.default(dataLoader, defaultBrowserId);
const userAgentOptions = new UserAgentOptions_1.default(dataLoader, browserEngineOptions);
exports.defaultBrowserEngine = browserEngineOptions.default;
const { log } = (0, Logger_1.default)(module);
let DefaultBrowserEmulator = DefaultBrowserEmulator_1 = class DefaultBrowserEmulator {
    constructor(emulationProfile) {
        this.logger = emulationProfile.logger ?? log.createChild(module);
        this.emulationProfile = emulationProfile;
        this.data = dataLoader.as(emulationProfile.userAgentOption);
        this.userAgentData = this.getUserAgentData();
        // set default device profile options
        emulationProfile.deviceProfile ?? (emulationProfile.deviceProfile = {});
        (0, configureDeviceProfile_1.default)(this.deviceProfile);
    }
    get userAgentString() {
        return this.emulationProfile.userAgentOption.string;
    }
    get browserEngine() {
        return this.emulationProfile.browserEngine;
    }
    get deviceProfile() {
        return this.emulationProfile.deviceProfile;
    }
    configure(emulationProfile) {
        var _a;
        emulationProfile.windowNavigatorPlatform ?? (emulationProfile.windowNavigatorPlatform = this.data.windowNavigator.navigator.platform._$value);
        emulationProfile.locale ?? (emulationProfile.locale = this.data.browserConfig.defaultLocale);
        emulationProfile.viewport ?? (emulationProfile.viewport = Viewports_1.default.getDefault(this.data.windowBaseFraming, this.data.windowFraming));
        emulationProfile.timezoneId ?? (emulationProfile.timezoneId = Intl.DateTimeFormat().resolvedOptions().timeZone);
        if (emulationProfile.upstreamProxyUrl) {
            emulationProfile.upstreamProxyIpMask ?? (emulationProfile.upstreamProxyIpMask = {});
            (_a = emulationProfile.upstreamProxyIpMask).ipLookupService ?? (_a.ipLookupService = lookupPublicIp_1.IpLookupServices.ipify);
        }
        this.domOverridesBuilder ?? (this.domOverridesBuilder = (0, loadDomOverrides_1.default)(this.emulationProfile, this.data, this.userAgentData));
    }
    onDnsConfiguration(settings) {
        (0, configureSessionDns_1.default)(this.emulationProfile, settings);
    }
    onTcpConfiguration(settings) {
        (0, configureSessionTcp_1.default)(this.emulationProfile, settings);
    }
    onTlsConfiguration(settings) {
        (0, configureSessionTls_1.default)(this.emulationProfile, settings);
    }
    beforeHttpRequest(resource) {
        (0, modifyHeaders_1.default)(this.emulationProfile, this.data, this.userAgentData, resource);
    }
    async onHttpAgentInitialized(agent) {
        const profile = this.emulationProfile;
        const upstreamProxyIpMask = profile.upstreamProxyIpMask;
        if (upstreamProxyIpMask) {
            upstreamProxyIpMask.publicIp ?? (upstreamProxyIpMask.publicIp = await (0, lookupPublicIp_1.default)(upstreamProxyIpMask.ipLookupService));
            upstreamProxyIpMask.proxyIp ?? (upstreamProxyIpMask.proxyIp = await (0, lookupPublicIp_1.default)(upstreamProxyIpMask.ipLookupService, agent, profile.upstreamProxyUrl));
            this.logger.info('PublicIp Lookup', {
                ...upstreamProxyIpMask,
            });
            this.domOverridesBuilder.add('webrtc', {
                localIp: upstreamProxyIpMask.publicIp,
                proxyIp: upstreamProxyIpMask.proxyIp,
            });
        }
    }
    onHttp2SessionConnect(request, settings) {
        (0, configureHttp2Session_1.default)(this.emulationProfile, this.data, request, settings);
    }
    onNewBrowser(browser, options) {
        (0, configureBrowserLaunchArgs_1.configureBrowserLaunchArgs)(browser.engine, options);
    }
    addDomOverride(runOn, script, args, callback) {
        if (runOn === 'page') {
            this.domOverridesBuilder.addPageScript(script, args, callback);
        }
        else {
            if (callback) {
                throw new Error("Sorry, we can't add a callback function to a Worker environment.");
            }
            this.domOverridesBuilder.addWorkerScript(script, args);
        }
        return true;
    }
    onNewPage(page) {
        // Don't await here! we want to queue all these up to run before the debugger resumes
        const devtools = page.devtoolsSession;
        const emulationProfile = this.emulationProfile;
        return Promise.all([
            (0, setUserAgent_1.default)(emulationProfile, devtools, this.userAgentData),
            (0, setTimezone_1.default)(emulationProfile, devtools),
            (0, setLocale_1.default)(emulationProfile, devtools),
            (0, setScreensize_1.default)(emulationProfile, page, devtools),
            (0, setActiveAndFocused_1.default)(emulationProfile, devtools),
            (0, setPageDomOverrides_1.default)(this.domOverridesBuilder, this.data, page),
            (0, setGeolocation_1.default)(emulationProfile, page),
        ]);
    }
    onNewWorker(worker) {
        const devtools = worker.devtoolsSession;
        return Promise.all([
            (0, setUserAgent_1.default)(this.emulationProfile, devtools, this.userAgentData),
            (0, setWorkerDomOverrides_1.default)(this.domOverridesBuilder, this.data, worker),
        ]);
    }
    getUserAgentData() {
        if (!this.data.windowNavigator.navigator.userAgentData)
            return null;
        const { browserVersion, uaClientHintsPlatformVersion } = this.emulationProfile.userAgentOption;
        const uaFullVersion = `${browserVersion.major}.0.${browserVersion.build}.${browserVersion.patch}`;
        const brands = this.data.windowNavigator.navigator.userAgentData.brands;
        const brandData = [brands['0'], brands['1'], brands['2']].map(x => ({
            brand: x.brand._$value,
            version: x.version._$value,
        }));
        return {
            uaFullVersion,
            brands: brandData,
            platform: this.data.windowNavigator.navigator.userAgentData.platform._$value,
            platformVersion: uaClientHintsPlatformVersion,
            architecture: 'x86',
            model: '',
            mobile: false,
            wow64: false,
        };
    }
    static shouldActivate(emulationProfile) {
        if (emulationProfile.userAgentOption &&
            !userAgentOptions.hasDataSupport(emulationProfile.userAgentOption)) {
            emulationProfile.logger?.info("DefaultBrowserEmulator doesn't have data file for the provided userAgentOption", { userAgentOption: emulationProfile.userAgentOption });
            return false;
        }
        // assign a browser engine and user agent option if not provided
        if (!emulationProfile.userAgentOption) {
            try {
                const { browserEngine, userAgentOption } = DefaultBrowserEmulator_1.selectBrowserMeta(emulationProfile.customEmulatorConfig?.userAgentSelector);
                emulationProfile.browserEngine = browserEngine;
                emulationProfile.userAgentOption = userAgentOption;
            }
            catch (e) {
                if (emulationProfile.customEmulatorConfig?.userAgentSelector) {
                    emulationProfile.logger?.error('Failed to instantiate a default browser engine.', {
                        error: e,
                    });
                }
                return false;
            }
        }
        return true;
    }
    static selectBrowserMeta(userAgentSelector) {
        const userAgentOption = (0, selectUserAgentOption_1.default)(userAgentSelector, userAgentOptions);
        const { browserName, browserVersion } = userAgentOption;
        const browserEngineId = `${browserName}-${browserVersion.major}-${browserVersion.minor}`;
        const browserEngineOption = (0, selectBrowserEngineOption_1.default)(browserEngineId, dataLoader.browserEngineOptions);
        const browserEngine = new BrowserEngine_1.default(browserEngineOption);
        return { browserEngine, userAgentOption };
    }
    static default() {
        return new BrowserEngine_1.default(exports.defaultBrowserEngine);
    }
};
DefaultBrowserEmulator = DefaultBrowserEmulator_1 = __decorate([
    IUnblockedPlugin_1.UnblockedPluginClassDecorator
], DefaultBrowserEmulator);
exports.default = DefaultBrowserEmulator;
//# sourceMappingURL=index.js.map