/**
 * Copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import os from 'os';
import path from 'path';
import { ManualPromise } from '@isomorphic/manualPromise';
import { wrapInASCIIBox } from '@utils/ascii';
import { BrowserType, kNoXServerRunningError } from '../browserType';
import { BidiBrowser } from './bidiBrowser';
import { kBrowserCloseMessageId, kShutdownSessionNewMessageId } from './bidiConnection';
import { createProfile } from './third_party/firefoxPrefs';
export class BidiFirefox extends BrowserType {
    constructor(parent) {
        super(parent, 'firefox');
    }
    executablePath() {
        return '';
    }
    async connectToTransport(transport, options) {
        return BidiBrowser.connect(this.attribution.playwright, transport, options);
    }
    doRewriteStartupLog(logs) {
        if (logs.includes(`as root in a regular user's session is not supported.`))
            logs = '\n' + wrapInASCIIBox(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.\nWorkaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ? ' in your GitHub Actions workflow file' : ''} when running Playwright.`, 1);
        if (logs.includes('no DISPLAY environment variable specified'))
            logs = '\n' + wrapInASCIIBox(kNoXServerRunningError, 1);
        return logs;
    }
    amendEnvironment(env) {
        if (!path.isAbsolute(os.homedir()))
            throw new Error(`Cannot launch Firefox with relative home directory. Did you set ${os.platform() === 'win32' ? 'USERPROFILE' : 'HOME'} to a relative path?`);
        env = {
            ...env,
            'MOZ_CRASHREPORTER': '1',
            'MOZ_CRASHREPORTER_NO_REPORT': '1',
            'MOZ_CRASHREPORTER_SHUTDOWN': '1',
        };
        if (os.platform() === 'linux') {
            // Always remove SNAP_NAME and SNAP_INSTANCE_NAME env variables since they
            // confuse Firefox: in our case, builds never come from SNAP.
            // See https://github.com/microsoft/playwright/issues/20555
            return { ...env, SNAP_NAME: undefined, SNAP_INSTANCE_NAME: undefined };
        }
        return env;
    }
    attemptToGracefullyCloseBrowser(transport) {
        this._attemptToGracefullyCloseBrowser(transport).catch(() => { });
    }
    async _attemptToGracefullyCloseBrowser(transport) {
        // Note that it's fine to reuse the transport, since our connection ignores kBrowserCloseMessageId.
        if (!transport.onmessage) {
            // browser.close does not work without an active session. If there is no connection
            // created with the transport, make sure to create a new session first.
            transport.send({ method: 'session.new', params: { capabilities: {} }, id: kShutdownSessionNewMessageId });
            await new Promise(resolve => {
                transport.onmessage = message => {
                    if (message.id === kShutdownSessionNewMessageId)
                        resolve(true);
                };
            });
        }
        transport.send({ method: 'browser.close', params: {}, id: kBrowserCloseMessageId });
    }
    supportsPipeTransport() {
        return false;
    }
    async prepareUserDataDir(options, userDataDir) {
        await createProfile({
            path: userDataDir,
            preferences: options.firefoxUserPrefs || {},
        });
    }
    async defaultArgs(options, isPersistent, userDataDir) {
        const { args = [], headless } = options;
        const userDataDirArg = args.find(arg => arg.startsWith('-profile') || arg.startsWith('--profile'));
        if (userDataDirArg)
            throw this._createUserDataDirArgMisuseError('--profile');
        if (args.find(arg => !arg.startsWith('-')))
            throw new Error('Arguments can not specify page to be opened');
        const firefoxArguments = ['--remote-debugging-port=0'];
        if (headless)
            firefoxArguments.push('--headless');
        else
            firefoxArguments.push('--foreground');
        firefoxArguments.push(`--profile`, userDataDir);
        firefoxArguments.push(...args);
        return firefoxArguments;
    }
    async waitForReadyState(options, browserLogsCollector) {
        const result = new ManualPromise();
        browserLogsCollector.onMessage(message => {
            const match = message.match(/WebDriver BiDi listening on (ws:\/\/.*)$/);
            if (match)
                result.resolve({ wsEndpoint: match[1] + '/session' });
        });
        return result;
    }
}
//# sourceMappingURL=bidiFirefox.js.map