/**
 * puppeteer-api 共享常量与 Chrome 启动环境工具
 */
const fs = require('fs');
const path = require('path');
const puppeteer = require('puppeteer-extra');

/** 默认 Chrome 可执行文件路径（生产环境可通过环境变量覆盖） */
const DEFAULT_CHROME_EXECUTABLE = '/www/wwwroot/puppeteer-api/.cache/puppeteer/chrome/linux-149.0.7827.22/chrome-linux64/chrome';

/** 默认 User-Agent，与 standard / real 双轨保持一致 */
const DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';

/** Chrome 启动基础参数：多实例 headless 场景下复用 */
const BASE_LAUNCH_ARGS = [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage',
    '--disable-gpu',
    '--disable-extensions',
    '--disable-background-networking',
    '--disable-software-rasterizer',
    '--no-first-run',
    '--no-default-browser-check',
    '--disable-breakpad',
    '--disable-crash-reporter',
];

/** puppeteer-api 专用运行时目录（与 server.js 同级 .runtime） */
const RUNTIME_DIR = path.join(__dirname, '..', '.runtime');

/**
 * 确保 .runtime 子目录存在且 www 用户可写
 * @param {string} name
 * @returns {string}
 */
function ensureRuntimeSubdir(name) {
    const dir = path.join(RUNTIME_DIR, name);
    fs.mkdirSync(dir, { recursive: true, mode: 0o777 });
    return dir;
}

/**
 * 解析 Chrome 可执行文件路径
 * @returns {string}
 */
function resolveChromeExecutable() {
    const candidates = [
        process.env.PUPPETEER_EXECUTABLE_PATH,
        process.env.CHROME_EXECUTABLE,
        DEFAULT_CHROME_EXECUTABLE,
    ].filter(Boolean);

    for (const candidate of candidates) {
        if (fs.existsSync(candidate)) {
            return candidate;
        }
    }

    try {
        const bundled = puppeteer.executablePath();
        if (bundled && fs.existsSync(bundled)) {
            return bundled;
        }
    } catch (_) {
        /* puppeteer 未内置浏览器时忽略 */
    }

    return candidates[0] || DEFAULT_CHROME_EXECUTABLE;
}

/**
 * 生产 Linux 常注入无效 DBUS 地址；删除而非设为 /dev/null
 * @returns {NodeJS.ProcessEnv}
 */
function buildBrowserLaunchEnv() {
    const env = { ...process.env };
    delete env.DBUS_SESSION_BUS_ADDRESS;
    delete env.DBUS_SYSTEM_BUS_ADDRESS;

    const xdgRuntime = ensureRuntimeSubdir('xdg-runtime');
    env.XDG_RUNTIME_DIR = xdgRuntime;
    env.XDG_CONFIG_HOME = ensureRuntimeSubdir('xdg-config');
    env.XDG_CACHE_HOME = ensureRuntimeSubdir('xdg-cache');
    env.TMPDIR = ensureRuntimeSubdir('tmp');

    return env;
}

/**
 * 校验 Chrome 可执行文件存在
 * @returns {string}
 */
function assertChromeExecutable() {
    const executablePath = resolveChromeExecutable();
    if (!fs.existsSync(executablePath)) {
        throw new Error(
            `Chrome 可执行文件不存在: ${executablePath}。请在 puppeteer-api 目录执行: npx puppeteer browsers install chrome`
        );
    }
    return executablePath;
}

/** 并发与超时配置（可通过环境变量覆盖） */
const MAX_CONCURRENT_BROWSERS = Math.max(1, parseInt(process.env.MAX_CONCURRENT_BROWSERS || '4', 10));
const MAX_CONCURRENT_BROWSERS_REAL = Math.max(1, parseInt(process.env.MAX_CONCURRENT_BROWSERS_REAL || '2', 10));
const QUEUE_TIMEOUT_MS = Math.max(5000, parseInt(process.env.QUEUE_TIMEOUT_MS || '120000', 10));
const API_INTERCEPT_TIMEOUT_MS = Math.max(10000, parseInt(process.env.API_INTERCEPT_TIMEOUT_MS || '30000', 10));
const API_INTERCEPT_TIMEOUT_REAL_MS = Math.max(
    API_INTERCEPT_TIMEOUT_MS,
    parseInt(process.env.API_INTERCEPT_TIMEOUT_REAL_MS || '90000', 10)
);

/** Captcha API 配置 */
const CAPTCHA_PROVIDER = (process.env.CAPTCHA_PROVIDER || 'capsolver').toLowerCase();
const CAPTCHA_API_KEY = process.env.CAPTCHA_API_KEY || '';
const CAPTCHA_MAX_WAIT_MS = Math.max(30000, parseInt(process.env.CAPTCHA_MAX_WAIT_MS || '120000', 10));

/** 会话 Cookie 持久化 TTL（毫秒） */
const SESSION_TTL_MS = Math.max(60000, parseInt(process.env.SESSION_TTL_MS || '1800000', 10));

module.exports = {
    DEFAULT_CHROME_EXECUTABLE,
    DEFAULT_UA,
    BASE_LAUNCH_ARGS,
    RUNTIME_DIR,
    ensureRuntimeSubdir,
    resolveChromeExecutable,
    buildBrowserLaunchEnv,
    assertChromeExecutable,
    MAX_CONCURRENT_BROWSERS,
    MAX_CONCURRENT_BROWSERS_REAL,
    QUEUE_TIMEOUT_MS,
    API_INTERCEPT_TIMEOUT_MS,
    API_INTERCEPT_TIMEOUT_REAL_MS,
    CAPTCHA_PROVIDER,
    CAPTCHA_API_KEY,
    CAPTCHA_MAX_WAIT_MS,
    SESSION_TTL_MS,
};
