#!/usr/bin/env node

/**
 * gateway.js
 * 
 * Gateway 生命周期管理（跨平台: Mac/Linux/Windows/容器）
 * 
 * 提供:
 *   stop()    — 先礼后兵，确保彻底关闭
 *   start()   — 后台启动 + 健康检查
 *   restart() — stop + start
 */

const { execSync } = require('child_process');

const PORT = 18789;
const isWin = process.platform === 'win32';

// ANSI 颜色
const colors = {
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  red: '\x1b[31m',
  nc: '\x1b[0m',
};

/**
 * 彻底停止 Gateway（先礼后兵）
 */
function stop() {
  // Step 1: 优雅关闭
  console.log('[停止] Step 1 — 优雅关闭...');
  try {
    execSync('openclaw gateway stop', { stdio: 'pipe', timeout: 10000 });
    console.log('[停止] ' + colors.green + 'Gateway 已发送停止信号' + colors.nc);
  } catch {
    console.log('[停止] Gateway 未在运行或已停止');
  }

  // 等 2 秒让优雅关闭执行
  execSync(isWin ? 'timeout /t 2 /nobreak >nul' : 'sleep 2', { stdio: 'ignore' });

  // Step 2: 检查残留进程并强杀
  console.log('[停止] Step 2 — 清理残留进程...');

  // 2a. 杀端口占用者
  try {
    if (isWin) {
      const netstat = execSync('netstat -ano | findstr :' + PORT + ' | findstr LISTENING', {
        encoding: 'utf8', stdio: 'pipe', timeout: 5000
      }).trim();
      const pids = [...new Set(netstat.split('\n').map(l => l.trim().split(/\s+/).pop()).filter(p => p && p !== '0'))];
      for (const pid of pids) {
        try {
          execSync('taskkill /F /PID ' + pid, { stdio: 'pipe', timeout: 5000 });
          console.log('[停止] 🔪 强杀端口占用进程 PID=' + pid);
        } catch {}
      }
    } else {
      const pids = execSync('lsof -i :' + PORT + ' -t 2>/dev/null', {
        encoding: 'utf8', stdio: 'pipe', timeout: 5000
      }).trim();
      if (pids) {
        for (const pid of pids.split('\n').filter(Boolean)) {
          try {
            execSync('kill -9 ' + pid, { stdio: 'pipe', timeout: 3000 });
            console.log('[停止] 🔪 强杀端口占用进程 PID=' + pid);
          } catch {}
        }
      }
    }
  } catch {
    // 没有端口占用，正常
  }

  // 2b. 杀所有 openclaw 相关进程（防止僵尸进程）
  try {
    if (!isWin) {
      const myPid = process.pid;
      const procs = execSync('pgrep -f "openclaw" 2>/dev/null || true', {
        encoding: 'utf8', stdio: 'pipe', timeout: 5000
      }).trim();
      if (procs) {
        for (const pid of procs.split('\n').filter(Boolean)) {
          if (pid === String(myPid)) continue;
          try {
            execSync('kill -9 ' + pid, { stdio: 'pipe', timeout: 3000 });
            console.log('[停止] 🔪 清理残留 openclaw 进程 PID=' + pid);
          } catch {}
        }
      }
    }
  } catch {}

  console.log('[停止] ' + colors.green + '清理完成' + colors.nc);

  // Step 3: 轮询等待端口释放
  const MAX_WAIT = 10;
  let portFree = false;

  for (let i = 0; i < MAX_WAIT; i++) {
    try {
      if (isWin) {
        execSync('netstat -ano | findstr :' + PORT + ' | findstr LISTENING', {
          stdio: 'pipe', timeout: 2000
        });
      } else {
        execSync('lsof -i :' + PORT + ' -t 2>/dev/null', { stdio: 'pipe', timeout: 2000 });
      }
      process.stdout.write('[等待] 端口 ' + PORT + ' 释放中... (' + (i + 1) + '/' + MAX_WAIT + 's)\r');
      execSync(isWin ? 'timeout /t 1 /nobreak >nul' : 'sleep 1', { stdio: 'ignore' });
    } catch {
      portFree = true;
      break;
    }
  }

  if (portFree) {
    console.log('[等待] ' + colors.green + '端口已释放' + colors.nc + '                    ');
  } else {
    console.log('[等待] ' + colors.yellow + '端口释放超时' + colors.nc);
  }

  return portFree;
}

/**
 * 启动 Gateway（后台 + 健康检查）
 */
function start() {
  console.log('[启动] 正在启动 Gateway...');

  if (isWin) {
    execSync('start /B openclaw gateway > %TEMP%\\openclaw-gateway.log 2>&1', {
      stdio: 'ignore', shell: true,
    });
  } else {
    execSync('nohup openclaw gateway run > /tmp/openclaw-gateway.log 2>&1 &', {
      stdio: 'ignore', shell: true,
    });
  }

  // 等待启动完成
  execSync(isWin ? 'timeout /t 3 /nobreak >nul' : 'sleep 3', { stdio: 'ignore' });

  // 注册 LaunchAgent（仅 macOS，Docker/Linux 无 systemd 跳过）
  if (process.platform === 'darwin') {
    try {
      execSync('openclaw gateway install', { stdio: 'pipe', timeout: 10000 });
      console.log('[守卫] ' + colors.green + 'LaunchAgent 已注册' + colors.nc);
    } catch (err) {
      console.log('[守卫] ' + colors.yellow + '注册失败: ' + (err.message || err) + colors.nc);
    }
  }

  // 健康检查
  try {
    execSync('openclaw health', { stdio: 'pipe', timeout: 5000 });
    console.log('[启动] ' + colors.green + 'Gateway 启动成功!' + colors.nc);
    console.log('');
    console.log('控制台: ' + colors.yellow + 'http://127.0.0.1:' + PORT + colors.nc);
    return true;
  } catch {
    console.log('[启动] ' + colors.yellow + 'Gateway 正在启动中...' + colors.nc);
    const logPath = isWin ? '%TEMP%\\openclaw-gateway.log' : '/tmp/openclaw-gateway.log';
    console.log('日志: ' + colors.yellow + 'tail -f ' + logPath + colors.nc);
    return false;
  }
}

/**
 * 重启 Gateway（stop + start）
 */
function restart() {
  stop();
  console.log('');
  return start();
}

module.exports = { stop, start, restart, PORT };
