"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.saveHmrPort = exports.normalizeWebpackConfig = exports.getWebpackConfig = void 0;
const tslib_1 = require("tslib");
const fs_1 = tslib_1.__importDefault(require("fs"));
const path_1 = tslib_1.__importDefault(require("path"));
const hippy_hmr_plugin_1 = tslib_1.__importDefault(require("@hippy/hippy-hmr-plugin"));
const qrcode_1 = tslib_1.__importDefault(require("qrcode"));
const safe_1 = require("colors/safe");
const log_1 = require("@/utils/log");
const url_1 = require("@/utils/url");
const config_1 = require("@/config");
const constants_1 = require("@/@types/constants");
const log = new log_1.Logger('webpack-util');
function getWebpackConfig(configPath) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        let webpackConfig;
        const webpackConfigPath = path_1.default.resolve(process.env.PWD, configPath);
        if (configPath && fs_1.default.existsSync(webpackConfigPath)) {
            webpackConfig = yield Promise.resolve().then(() => tslib_1.__importStar(require(webpackConfigPath)));
        }
        return (webpackConfig === null || webpackConfig === void 0 ? void 0 : webpackConfig.default) || webpackConfig;
    });
}
exports.getWebpackConfig = getWebpackConfig;
function normalizeWebpackConfig(versionId, config) {
    const enableRemoteDebug = isRemoteDebugEnabled(config);
    if (!enableRemoteDebug)
        return log.warn('remote debug is disabled!');
    normalizeRemoteDebug(versionId, config);
    appendHMRPlugin(versionId, config);
}
exports.normalizeWebpackConfig = normalizeWebpackConfig;
function normalizeRemoteDebug(versionId, config) {
    var _a;
    (_a = config.devServer).remote || (_a.remote = {
        protocol: 'http',
        host: '127.0.0.1',
        port: 38989,
        qrcode: false,
    });
    const { protocol, host, port, qrcode: qrcodeFn } = config.devServer.remote;
    if (host && port && protocol === false) {
        log.warn('you must config remote host, port and protocol!');
        process.exit(1);
    }
    // only print qrcode when use remote debug server
    const needVersionId = needPublicPathWithVersionId(host);
    if (!needVersionId)
        return;
    const publicPath = getPublicPath(versionId, config.devServer.remote);
    config.output.publicPath = publicPath;
    log.warn(safe_1.bold(safe_1.yellow(`webpack publicPath is set as: ${config.output.publicPath}`)));
    const bundleUrl = url_1.makeUrl(`${config.output.publicPath}index.bundle`, {
        debugUrl: url_1.makeUrl(`${url_1.getWSProtocolByHttpProtocol(protocol)}://${host}:${port}/debugger-proxy`),
    });
    const homeUrl = `${protocol}://${host}:${port}/extensions/home.html?hash=${versionId}`;
    config.devServer.cb = () => {
        process.nextTick(() => {
            printDebugInfo(qrcodeFn, { bundleUrl, homeUrl });
        });
    };
}
function appendHMRPlugin(versionId, config) {
    if (config.devServer.hot && config.devServer.liveReload === false)
        return;
    const hotManifestPublicPath = getPublicPath(versionId, config.devServer.remote);
    const i = config.plugins.findIndex((plugin) => plugin.constructor.name === hippy_hmr_plugin_1.default.name);
    if (i !== -1) {
        config.plugins.splice(i, 1);
    }
    config.plugins.push(new hippy_hmr_plugin_1.default({ hotManifestPublicPath }));
}
/**
 * remote debug is enabled by default if enable webpack-dev-server
 * you could disable it by set `devServer.remote: false`
 */
function isRemoteDebugEnabled(webpackConfig) {
    return !(!webpackConfig.devServer || webpackConfig.devServer.remote === false);
}
function printDebugInfo(qrcodeFn, { bundleUrl, homeUrl }) {
    log.info('bundleUrl: %s', safe_1.bold(safe_1.green(bundleUrl)));
    log.info('find debug page on: %s', safe_1.bold(safe_1.green(homeUrl)));
    if (qrcodeFn && typeof qrcodeFn === 'function') {
        const qrcodeStr = qrcodeFn(bundleUrl);
        log.info('bundleUrl scheme: %s', safe_1.bold(safe_1.green(qrcodeStr)));
        qrcode_1.default.toString(qrcodeStr, {
            small: true,
            type: 'terminal',
        }, (e, qrcodeStr) => {
            if (e)
                log.error('draw qrcode of bundleUrl failed: %j', (e === null || e === void 0 ? void 0 : e.stack) || e);
            log.info('scheme qrcode:\n%s', qrcodeStr);
        });
    }
}
/**
 * when use debug-server-next in local, no need to set webpack `publicPath` field,
 * only should set `hotManifestPublicPath` field
 */
function needPublicPathWithVersionId(host) {
    return !(host === 'localhost' || host === '127.0.0.1');
}
function getPublicPath(versionId, { host, port, protocol }) {
    if (host === constants_1.DEFAULT_REMOTE.host)
        return `${constants_1.PUBLIC_RESOURCE}${versionId}/`;
    if (!needPublicPathWithVersionId(host))
        return `${protocol}://${host}:${port}/`;
    return `${protocol}://${host}:${port}/${versionId}/`;
}
/**
 * hippy-dev process will save hmrPort to file,
 * hippy-debug process will auto reverse hmrPort when device re-connect.
 */
function saveHmrPort(hmrPort) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { cachePath } = config_1.config;
        fs_1.default.mkdirSync(cachePath, { recursive: true });
        return fs_1.default.writeFileSync(config_1.config.hmrPortPath, String(hmrPort));
    });
}
exports.saveHmrPort = saveHmrPort;
