#!/usr/bin/env node

/**
 * ============================================================================
 * MyClaw Prepare - 智能初始化链条
 * ============================================================================
 *
 * 使用: myclaw prepare
 *
 * 按顺序执行以下检测和操作：
 *   Step 1: 检测环境（Windows / Mac / Linux-WSL）
 *   Step 2: 检测 Chrome 浏览器
 *   Step 3: 检测 OpenClaw → 未装则安装
 *   Step 4: 已装 → 执行 Patch
 *
 * 设计原则：
 *   - 每一步都可以被单独跳过
 *   - 幂等：多次运行不会出错
 *   - 交互式：关键步骤询问用户
 * ============================================================================
 */

const { execSync } = require('child_process');
const os = require('os');
const path = require('path');
const readline = require('readline');

// ============================================================================
// 颜色
// ============================================================================

const isWindows = os.platform() === 'win32';
const C = isWindows
  ? { r: '', g: '', y: '', b: '', nc: '' }
  : { r: '\x1b[31m', g: '\x1b[32m', y: '\x1b[33m', b: '\x1b[34m', nc: '\x1b[0m' };

const BAR = '========================================';

// 检测是否在 npm postinstall 中运行（非交互模式）
const isPostInstall = process.env.npm_lifecycle_event === 'postinstall';

// ============================================================================
// 文件日志（用于调试 postinstall 等场景）
// ============================================================================

const fs = require('fs');
const LOG_PATH = path.join(os.tmpdir(), 'myclaw-prepare.log');

function writeLog(msg) {
  const ts = new Date().toISOString();
  const line = '[' + ts + '] ' + msg + '\n';
  try {
    fs.appendFileSync(LOG_PATH, line, 'utf8');
  } catch {}
}

// ============================================================================
// 工具：交互式问答
// ============================================================================

function ask(question) {
  return new Promise((resolve) => {
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
    });
    rl.question(question, (answer) => {
      rl.close();
      resolve(answer.trim().toLowerCase());
    });
  });
}

function log(tag, msg) {
  console.log('[' + tag + '] ' + msg);
}

function logOK(msg) {
  console.log('  ' + C.g + '[OK]' + C.nc + ' ' + msg);
}

function logWarn(msg) {
  console.log('  ' + C.y + '[!]' + C.nc + ' ' + msg);
}

function logFail(msg) {
  console.log('  ' + C.r + '[X]' + C.nc + ' ' + msg);
}

// ============================================================================
// Step 1: 检测环境
// ============================================================================

function detectEnv() {
  const platform = os.platform();

  if (platform === 'win32') {
    return 'windows';
  }

  if (platform === 'darwin') {
    return 'mac';
  }

  // Linux 下判断是否在 WSL 内
  if (platform === 'linux') {
    try {
      const release = require('fs').readFileSync('/proc/version', 'utf8');
      if (release.toLowerCase().includes('microsoft')) {
        return 'wsl';
      }
    } catch {}
    return 'linux';
  }

  return 'unknown';
}

// ============================================================================
// Step 2: 检测 Chrome
// ============================================================================

function checkChrome(env) {
  log('Step 2', '检测 Chrome 浏览器...');

  let found = false;

  if (env === 'mac') {
    try {
      require('fs').accessSync('/Applications/Google Chrome.app');
      found = true;
    } catch {}
  } else if (env === 'windows') {
    const chromeLocations = [
      path.join(process.env.PROGRAMFILES || '', 'Google', 'Chrome', 'Application', 'chrome.exe'),
      path.join(process.env['PROGRAMFILES(X86)'] || '', 'Google', 'Chrome', 'Application', 'chrome.exe'),
      path.join(process.env.LOCALAPPDATA || '', 'Google', 'Chrome', 'Application', 'chrome.exe'),
    ];
    found = chromeLocations.some((loc) => {
      try { require('fs').accessSync(loc); return true; } catch { return false; }
    });
  } else {
    // Linux/WSL
    try {
      execSync('which google-chrome || which google-chrome-stable || which chromium-browser', {
        stdio: 'pipe',
      });
      found = true;
    } catch {}
  }

  if (found) {
    logOK('Chrome 已安装');
  } else {
    logWarn('未检测到 Chrome 浏览器');
    console.log('');
    console.log('  请前往以下地址下载安装 Chrome:');
    console.log('  ' + C.y + 'https://www.google.cn/intl/zh-CN/chrome/' + C.nc);
    console.log('');
    console.log('  (安装后重新运行 ' + C.y + 'myclaw prepare' + C.nc + ' 即可)');
    console.log('');
  }

  return found;
}

// ============================================================================
// Step 3: 检测 OpenClaw 安装状态
// ============================================================================

function checkOpenClaw(env) {
  log('Step 3', '检测 OpenClaw...');

  if (env === 'windows') {
    // Windows 上，OpenClaw 跑在 WSL 里
    // 先检查 WSL 是否可用
    try {
      execSync('wsl echo ok', { stdio: 'pipe', timeout: 10000 });
    } catch {
      logWarn('WSL 未就绪');
      return 'no-wsl';
    }

    // 再检查 OpenClaw distro
    try {
      const list = execSync('wsl -l -q', { stdio: 'pipe' }).toString('utf16le');
      if (!list.includes('OpenClaw')) {
        logWarn('OpenClaw Linux 环境未导入');
        return 'no-distro';
      }
    } catch {
      logWarn('无法获取 WSL 发行版列表');
      return 'no-distro';
    }

    // 检查 WSL 内 openclaw 命令
    try {
      execSync('wsl -d OpenClaw -- which openclaw', { stdio: 'pipe', timeout: 10000 });
      logOK('OpenClaw 已安装 (WSL)');
      return 'installed';
    } catch {
      logWarn('OpenClaw 命令未找到');
      return 'no-openclaw';
    }
  }

  // Mac / Linux / WSL 内部
  try {
    execSync('which openclaw', { stdio: 'pipe' });
    logOK('OpenClaw 已安装');
    return 'installed';
  } catch {
    logWarn('OpenClaw 未安装');
    return 'not-installed';
  }
}

// ============================================================================
// Step 3b: 安装 OpenClaw
// ============================================================================

async function installOpenClaw(env, openclawStatus) {
  if (env === 'windows') {
    // Windows 统一走 WSL2 流程
    console.log('');
    console.log('  Windows 环境需要通过 WSL2 安装 OpenClaw');

    if (openclawStatus === 'no-wsl') {
      console.log('  即将启动 WSL2 安装向导 (Phase 1)...');
    } else {
      console.log('  即将导入 OpenClaw Linux 环境 (Phase 2)...');
    }

    console.log('');
    const wsl2 = require('./wsl2');
    wsl2.run();
    return false; // 需要重启或再次运行
  }

  // Mac / Linux
  if (isPostInstall) {
    // postinstall 模式下不交互，跳过安装
    console.log('');
    console.log('  OpenClaw 未安装，请手动运行:');
    console.log('  ' + C.y + 'myclaw install' + C.nc);
    console.log('');
    return false;
  }

  console.log('');
  const answer = await ask(
    '  是否现在安装 OpenClaw? (y/n): '
  );

  if (answer === 'y' || answer === 'yes' || answer === '') {
    console.log('');
    log('安装', '开始安装 OpenClaw...');
    console.log('');

    try {
      if (env === 'mac') {
        execSync('curl -fsSL https://openclaw.ai/install.sh | bash', {
          stdio: 'inherit',
        });
      } else {
        execSync('curl -fsSL https://openclaw.ai/install.sh | bash', {
          stdio: 'inherit',
        });
      }
      console.log('');
      logOK('OpenClaw 安装完成!');
      return true;
    } catch (err) {
      logFail('安装失败: ' + err.message);
      return false;
    }
  } else {
    console.log('');
    console.log('  跳过安装。你可以稍后运行:');
    console.log('  ' + C.y + 'myclaw install' + C.nc);
    console.log('');
    return false;
  }
}

// ============================================================================
// Step 4: 执行 Patch
// ============================================================================

function runPatchStep(env) {
  log('Step 4', '执行 MyClaw Patch...');

  try {
    execSync('node "' + path.join(__dirname, 'index.js') + '" patch', {
      stdio: 'inherit',
    });
    logOK('Patch 注入成功');
    return true;
  } catch (err) {
    logWarn('Patch 跳过或失败: ' + err.message);
    return false;
  }
}

// ============================================================================
// Step 5 (Windows only): 生成桌面启动器
// ============================================================================

function createDesktopLauncher() {
  log('Step 5', '生成桌面启动器...');
  console.log('');
  try {
    // 直接调用 myclaw bat，它是桌面启动器的唯一入口
    execSync('node "' + path.join(__dirname, 'index.js') + '" bat', { stdio: 'inherit' });
    return true;
  } catch (err) {
    logWarn('桌面启动器创建失败');
    console.log('  你可以手动运行: ' + C.y + 'myclaw bat' + C.nc);
    return false;
  }
}

// ============================================================================
// 主入口
// ============================================================================

async function run() {
  writeLog('=== prepare start (postinstall=' + isPostInstall + ', version=' + require('./package.json').version + ')');

  console.log('');
  console.log(C.b + BAR + C.nc);
  console.log(C.b + '  MyClaw 初始化向导' + C.nc);
  console.log(C.b + BAR + C.nc);
  console.log('');

  // === Step 1: 检测环境 ===
  const env = detectEnv();
  log('Step 1', '检测运行环境...');
  writeLog('Step 1: env=' + env);

  const envNames = {
    windows: 'Windows',
    mac: 'macOS',
    linux: 'Linux',
    wsl: 'Linux (WSL)',
    unknown: '未知',
  };
  logOK('当前环境: ' + C.y + (envNames[env] || env) + C.nc);
  console.log('');

  // === Step 2: 检测 Chrome ===
  const hasChrome = checkChrome(env);
  writeLog('Step 2: chrome=' + hasChrome);
  console.log('');

  // === Step 3: 检测 OpenClaw ===
  const openclawStatus = checkOpenClaw(env);
  writeLog('Step 3: openclaw=' + openclawStatus);
  console.log('');

  if (openclawStatus !== 'installed') {
    // 需要安装
    log('提示', 'OpenClaw 需要安装');
    const installed = await installOpenClaw(env, openclawStatus);
    writeLog('Step 3b: install result=' + installed);

    if (!installed) {
      // 安装未完成（可能需要重启/手动操作）
      console.log('');
      console.log(BAR);
      console.log('  安装流程已启动');
      console.log('  完成后请重新运行: ' + C.y + 'myclaw prepare' + C.nc);
      console.log(BAR);
      console.log('');
      writeLog('=== prepare end (install incomplete)');
      return;
    }

    console.log('');
  }

  // === Step 4: Patch ===
  const { AUTO_PATCH } = require('./config');
  writeLog('Step 4: AUTO_PATCH=' + AUTO_PATCH + ', env=' + env);
  if (AUTO_PATCH && env !== 'windows') {
    // Mac/Linux 直接 patch
    runPatchStep(env);
    writeLog('Step 4: patch executed');
    console.log('');
  } else if (!AUTO_PATCH) {
    log('Step 4', 'Patch 已跳过 (AUTO_PATCH=false)');
    console.log('  手动执行: ' + C.y + 'myclaw patch' + C.nc);
    console.log('');
  }

  // === Step 5: Windows 桌面启动器 ===
  if (env === 'windows') {
    createDesktopLauncher();
    writeLog('Step 5: desktop launcher created');
    console.log('');
  }

  // === 完成 ===
  console.log(C.g + BAR + C.nc);
  console.log(C.g + '  初始化完成!' + C.nc);
  console.log(C.g + BAR + C.nc);
  console.log('');

  if (env === 'windows') {
    console.log('  双击桌面的 ' + C.y + 'OpenClaw' + C.nc + ' 图标即可启动');
  } else {
    console.log('  运行 ' + C.y + 'openclaw gateway' + C.nc + ' 启动服务');
    console.log('  然后打开 ' + C.y + 'http://127.0.0.1:18789' + C.nc);
  }
  console.log('');
  writeLog('=== prepare end (success)');
}

module.exports = { run };
