#!/usr/bin/env node

import { spawn } from "child_process";
import { existsSync, readdirSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { homedir } from "node:os";

const MIRRORS = [
  { host: "https://npmmirror.com/mirrors/playwright", name: "淘宝镜像" },
  { host: "", name: "官方源" },
];

// npm postinstall 会吞掉 stdout，用 stderr 输出状态让用户看到
function status(msg) {
  process.stderr.write(`\n[browsers] ${msg}\n`);
}

/**
 * 获取当前 playwright 包需要的 chromium 版本号
 * 从 playwright-core 的 registry 中读取
 */
function getRequiredChromiumVersion() {
  try {
    // 尝试从 playwright-core 的 registry 文件读取
    const registryPaths = [
      join(import.meta.url.replace('file:///', '').replace(/\/scripts\/.*/, ''), 'node_modules', 'playwright-core', 'browsers.json'),
      join(process.cwd(), 'node_modules', 'playwright-core', 'browsers.json'),
    ];

    // 也检查全局安装路径
    const globalPaths = [
      join(homedir(), 'AppData', 'Roaming', 'npm', 'node_modules', 'aggroot', 'node_modules', 'playwright-core', 'browsers.json'),
      join('/usr', 'local', 'lib', 'node_modules', 'aggroot', 'node_modules', 'playwright-core', 'browsers.json'),
    ];

    for (const p of [...registryPaths, ...globalPaths]) {
      const filePath = p.startsWith('/') ? p : p.replace(/\//g, '\\');
      if (existsSync(filePath)) {
        const data = JSON.parse(readFileSync(filePath, 'utf-8'));
        const chromium = data.browsers?.find(b => b.name === 'chromium');
        if (chromium?.revision) return chromium.revision;
      }
    }
  } catch { /* fallback to npx */ }
  return null;
}

/**
 * 检查 Playwright Chromium 浏览器是否已安装且版本匹配
 */
function isChromiumInstalled() {
  const playwrightDir = process.platform === 'win32'
    ? join(homedir(), 'AppData', 'Local', 'ms-playwright')
    : join(homedir(), '.cache', 'ms-playwright');

  if (!existsSync(playwrightDir)) return false;

  // 查找已安装的 chromium 目录
  const dirs = readdirSync(playwrightDir, { withFileTypes: true })
    .filter(d => d.isDirectory() && d.name.startsWith('chromium-'))
    .map(d => d.name);

  if (dirs.length === 0) return false;

  // 检查是否有可执行文件
  const latestDir = dirs.sort().pop();
  const exeName = process.platform === 'win32' ? 'chrome.exe' : 'chrome';
  const possiblePaths = [
    join(playwrightDir, latestDir, 'chrome-win64', exeName),
    join(playwrightDir, latestDir, 'chrome-linux', exeName),
    join(playwrightDir, latestDir, 'chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'),
  ];

  return possiblePaths.some(p => existsSync(p));
}

function tryInstall(mirror) {
  return new Promise((resolve) => {
    const env = { ...process.env };
    if (mirror.host) {
      env.PLAYWRIGHT_DOWNLOAD_HOST = mirror.host;
    } else {
      delete env.PLAYWRIGHT_DOWNLOAD_HOST;
    }

    status(`正在下载 Playwright Chromium (${mirror.name})...`);

    const child = spawn("npx", ["playwright", "install", "chromium"], {
      stdio: "inherit",
      shell: true,
      env,
    });

    let timedOut = false;
    const timer = setTimeout(() => {
      timedOut = true;
      child.kill();
    }, 120000);

    child.on("close", (code) => {
      clearTimeout(timer);
      resolve(timedOut ? "timeout" : code);
    });

    child.on("error", () => {
      clearTimeout(timer);
      resolve("error");
    });
  });
}

(async () => {
  // 先检查是否已安装
  if (isChromiumInstalled()) {
    status("Playwright Chromium 已安装，跳过下载。");
    return;
  }

  status("Playwright Chromium 未安装，开始下载...");

  for (const mirror of MIRRORS) {
    const result = await tryInstall(mirror);
    if (result === 0) {
      status("浏览器安装完成。");
      return;
    }
    if (mirror === MIRRORS[0]) {
      status(`${mirror.name}下载失败，尝试${MIRRORS[1].name}...`);
    }
  }
  status("浏览器安装失败，将在首次使用时自动下载。");
})();
