'use strict';

const { exec } = require('child_process');
const path = require('path');

function resolvePath(workspace, p) {
  if (!p) return workspace;
  if (path.isAbsolute(p)) return p;
  return path.join(workspace, p);
}

function runCommandTool(workspace, args, abortSignal) {
  return new Promise((resolve) => {
    const cmd = args.command;
    const timeoutSec = Number(args.timeout || 0);
    const cwd = resolvePath(workspace, args.working_dir || '.');
    if (!cmd) return resolve({ success: false, error: 'command 不能为空' });
    if (abortSignal && abortSignal.aborted) {
      return resolve({ success: false, error: '任务被用户取消', cancelled: true });
    }
    const timeoutMs = Math.max(0, timeoutSec) * 1000;
    let finished = false;
    const child = exec(cmd, { cwd, timeout: timeoutMs, maxBuffer: 10 * 1024 * 1024, shell: true }, (err, stdout, stderr) => {
      if (finished) return;
      finished = true;
      if (abortSignal) abortSignal.removeEventListener('abort', onAbort);
      const output = [stdout, stderr].filter(Boolean).join('');
      if (err) {
        const isTimeout = err.killed && err.signal === 'SIGTERM';
        return resolve({
          success: false,
          status: isTimeout ? 'timeout' : 'error',
          error: err.message,
          return_code: err.code,
          output,
          timeout: timeoutSec,
        });
      }
      resolve({ success: true, status: 'ok', output });
    });
    const onAbort = () => {
      if (finished) return;
      finished = true;
      try {
        child.kill('SIGTERM');
      } catch (_) {}
      return resolve({ success: false, error: '任务被用户取消', cancelled: true });
    };
    if (abortSignal) abortSignal.addEventListener('abort', onAbort, { once: true });
  });
}

module.exports = { runCommandTool };
