"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const util_1 = require("util");
const getBrowserLauncherCb = require("@httptoolkit/browser-launcher");
const browser_launcher_1 = require("@httptoolkit/browser-launcher");
const error_tracking_1 = require("./error-tracking");
const util_2 = require("./util");
const getBrowserLauncher = util_1.promisify(getBrowserLauncherCb);
const updateBrowserCache = util_1.promisify(browser_launcher_1.update);
const browserConfigPath = (configPath) => path.join(configPath, 'browsers.json');
async function checkBrowserConfig(configPath) {
    // It's not clear why, but sometimes the browser config can become corrupted, so it's not valid JSON
    // If that happens browser-launcher can hit issues. To avoid that entirely, we check it here on startup.
    const browserConfig = browserConfigPath(configPath);
    try {
        const rawConfig = await util_2.readFile(browserConfig, 'utf8');
        JSON.parse(rawConfig);
    }
    catch (error) {
        if (error.code === 'ENOENT')
            return;
        console.warn(`Failed to read browser config cache from ${browserConfig}, clearing.`, error);
        return util_2.deleteFile(browserConfig).catch((err) => {
            // There may be possible races around here - as long as the file's gone, we're happy
            if (err.code === 'ENOENT')
                return;
            console.error('Failed to clear broken config file:', err);
            error_tracking_1.reportError(err);
        });
    }
}
exports.checkBrowserConfig = checkBrowserConfig;
let launcher;
function getLauncher(configPath) {
    if (!launcher) {
        const browserConfig = browserConfigPath(configPath);
        launcher = getBrowserLauncher(browserConfig);
        launcher.then(async () => {
            // Async after first creating the launcher, we trigger a background cache update.
            // This can be *synchronously* expensive (spawns 10s of procs, 10+ms sync per
            // spawn on unix-based OSs) so defer briefly.
            await util_2.delay(2000);
            try {
                await updateBrowserCache(browserConfig);
                console.log('Browser cache updated');
                // Need to reload the launcher after updating the cache:
                launcher = getBrowserLauncher(browserConfig);
            }
            catch (e) {
                error_tracking_1.reportError(e);
            }
        });
        // Reset & retry if this fails somehow:
        launcher.catch((e) => {
            error_tracking_1.reportError(e);
            launcher = undefined;
        });
    }
    return launcher;
}
exports.getAvailableBrowsers = async (configPath) => {
    return (await getLauncher(configPath)).browsers;
};
exports.launchBrowser = async (url, options, configPath) => {
    const launcher = await getLauncher(configPath);
    const browserInstance = await util_1.promisify(launcher)(url, options);
    browserInstance.process.on('error', (e) => {
        // If nothing else is listening for this error, this acts as default
        // fallback error handling: log & report & don't crash.
        if (browserInstance.process.listenerCount('error') === 1) {
            console.log('Browser launch error');
            error_tracking_1.reportError(e);
        }
    });
    return browserInstance;
};
//# sourceMappingURL=browsers.js.map