"use strict";
/// <reference path="../typings/chrome-aws-lambda.d.ts" />
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
const fs_1 = require("fs");
const lambdafs_1 = __importDefault(require("lambdafs"));
const path_1 = require("path");
const url_1 = require("url");
if (/^AWS_Lambda_nodejs(?:10|12|14|16)[.]x$/.test(process.env.AWS_EXECUTION_ENV) === true) {
    if (process.env.FONTCONFIG_PATH === undefined) {
        process.env.FONTCONFIG_PATH = '/tmp/aws';
    }
    if (process.env.LD_LIBRARY_PATH === undefined) {
        process.env.LD_LIBRARY_PATH = '/tmp/aws/lib';
    }
    else if (process.env.LD_LIBRARY_PATH.startsWith('/tmp/aws/lib') !== true) {
        process.env.LD_LIBRARY_PATH = [...new Set(['/tmp/aws/lib', ...process.env.LD_LIBRARY_PATH.split(':')])].join(':');
    }
}
class Chromium {
    /**
     * Downloads or symlinks a custom font and returns its basename, patching the environment so that Chromium can find it.
     * If not running on AWS Lambda nor Google Cloud Functions, `null` is returned instead.
     */
    static font(input) {
        if (Chromium.headless !== true) {
            return null;
        }
        if (process.env.HOME === undefined) {
            process.env.HOME = '/tmp';
        }
        if ((0, fs_1.existsSync)(`${process.env.HOME}/.fonts`) !== true) {
            (0, fs_1.mkdirSync)(`${process.env.HOME}/.fonts`);
        }
        return new Promise((resolve, reject) => {
            if (/^https?:[/][/]/i.test(input) !== true) {
                input = `file://${input}`;
            }
            const url = new url_1.URL(input);
            const output = `${process.env.HOME}/.fonts/${url.pathname.split('/').pop()}`;
            if ((0, fs_1.existsSync)(output) === true) {
                return resolve(output.split('/').pop());
            }
            if (url.protocol === 'file:') {
                (0, fs_1.access)(url.pathname, (error) => {
                    if (error != null) {
                        return reject(error);
                    }
                    (0, fs_1.symlink)(url.pathname, output, (error) => {
                        return error != null ? reject(error) : resolve(url.pathname.split('/').pop());
                    });
                });
            }
            else {
                let handler = url.protocol === 'http:' ? require('http').get : require('https').get;
                handler(input, (response) => {
                    if (response.statusCode !== 200) {
                        return reject(`Unexpected status code: ${response.statusCode}.`);
                    }
                    const stream = (0, fs_1.createWriteStream)(output);
                    stream.once('error', (error) => {
                        return reject(error);
                    });
                    response.on('data', (chunk) => {
                        stream.write(chunk);
                    });
                    response.once('end', () => {
                        stream.end(() => {
                            return resolve(url.pathname.split('/').pop());
                        });
                    });
                });
            }
        });
    }
    /**
     * Returns a list of additional Chromium flags recommended for serverless environments.
     * The canonical list of flags can be found on https://peter.sh/experiments/chromium-command-line-switches/.
     */
    static get args() {
        const result = [
            '--allow-running-insecure-content',
            '--autoplay-policy=user-gesture-required',
            '--disable-component-update',
            '--disable-domain-reliability',
            '--disable-features=AudioServiceOutOfProcess,IsolateOrigins,site-per-process',
            '--disable-print-preview',
            '--disable-setuid-sandbox',
            '--disable-site-isolation-trials',
            '--disable-speech-api',
            '--disable-web-security',
            '--disk-cache-size=33554432',
            '--enable-features=SharedArrayBuffer',
            '--hide-scrollbars',
            '--ignore-gpu-blocklist',
            '--in-process-gpu',
            '--mute-audio',
            '--no-default-browser-check',
            '--no-pings',
            '--no-sandbox',
            '--no-zygote',
            '--use-gl=angle',
            '--use-angle=swiftshader',
            '--window-size=1920,1080', // https://source.chromium.org/search?q=lang:cpp+symbol:kWindowSize&ss=chromium
        ];
        if (Chromium.headless === true) {
            result.push('--single-process'); // https://source.chromium.org/search?q=lang:cpp+symbol:kSingleProcess&ss=chromium
        }
        else {
            result.push('--start-maximized'); // https://source.chromium.org/search?q=lang:cpp+symbol:kStartMaximized&ss=chromium
        }
        return result;
    }
    /**
     * Returns sensible default viewport settings.
     */
    static get defaultViewport() {
        return {
            deviceScaleFactor: 1,
            hasTouch: false,
            height: 1080,
            isLandscape: true,
            isMobile: false,
            width: 1920,
        };
    }
    /**
     * Inflates the current version of Chromium and returns the path to the binary.
     * If not running on AWS Lambda nor Google Cloud Functions, `null` is returned instead.
     */
    static get executablePath() {
        if (Chromium.headless !== true) {
            return Promise.resolve(null);
        }
        if ((0, fs_1.existsSync)('/tmp/chromium') === true) {
            for (const file of (0, fs_1.readdirSync)('/tmp')) {
                if (file.startsWith('core.chromium') === true) {
                    (0, fs_1.unlinkSync)(`/tmp/${file}`);
                }
            }
            return Promise.resolve('/tmp/chromium');
        }
        const input = (0, path_1.join)(__dirname, '..', 'bin');
        const promises = [
            lambdafs_1.default.inflate(`${input}/chromium.br`),
            lambdafs_1.default.inflate(`${input}/swiftshader.tar.br`),
        ];
        if (/^AWS_Lambda_nodejs(?:10|12|14|16)[.]x$/.test(process.env.AWS_EXECUTION_ENV) === true) {
            promises.push(lambdafs_1.default.inflate(`${input}/aws.tar.br`));
        }
        return Promise.all(promises).then((result) => result.shift());
    }
    /**
     * Returns a boolean indicating if we are running on AWS Lambda or Google Cloud Functions.
     * False is returned if Serverless environment variables `IS_LOCAL` or `IS_OFFLINE` are set.
     */
    static get headless() {
        if (process.env.IS_LOCAL !== undefined || process.env.IS_OFFLINE !== undefined) {
            return false;
        }
        const environments = [
            'AWS_LAMBDA_FUNCTION_NAME',
            'FUNCTION_NAME',
            'FUNCTION_TARGET',
            'FUNCTIONS_EMULATOR',
        ];
        return environments.some((key) => process.env[key] !== undefined);
    }
    /**
     * Overloads puppeteer with useful methods and returns the resolved package.
     */
    static get puppeteer() {
        for (const overload of ['Browser', 'BrowserContext', 'ElementHandle', 'FrameManager', 'Page']) {
            require(`${__dirname}/puppeteer/lib/${overload}`);
        }
        try {
            return require('puppeteer');
        }
        catch (error) {
            if (error.code !== 'MODULE_NOT_FOUND') {
                throw error;
            }
            return require('puppeteer-core');
        }
    }
}
module.exports = Chromium;
//# sourceMappingURL=index.js.map