import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import _regeneratorRuntime from '@babel/runtime/regenerator';
import { _ as __awaiter } from '../tslib.es6-848120af.js';
import { execCommand } from '../node/node-command.mjs';
import { getChildProcess } from '../nodejs/child_process.mjs';
import { getFs } from '../nodejs/fs.mjs';
import { getPath } from '../nodejs/path.mjs';
import { getChalk } from '../third-party/chalk.mjs';
import '@babel/runtime/helpers/typeof';

/**
 * 异步执行命令，返回 stdout 字符串
 */
function execAsync(command, cwd) {
  return new Promise(function (resolve) {
    var _getChildProcess = getChildProcess(),
      exec = _getChildProcess.exec;
    exec(command, {
      cwd: cwd,
      encoding: 'utf-8'
    }, function (err, stdout) {
      resolve(err ? '' : stdout || '');
    });
  });
}
/**
 * 检查单个 git 仓库的状态（是否 clean、是否已 push）
 * @param {string} subDir - git 仓库目录路径
 * @param {*} chalk - chalk 实例
 */
function checkSingleRepo(subDir, chalk) {
  return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
    var _yield$Promise$all, _yield$Promise$all2, statusOutput, aheadCount, count;
    return _regeneratorRuntime.wrap(function (_context) {
      while (1) switch (_context.prev = _context.next) {
        case 0:
          _context.next = 1;
          return Promise.all([execAsync('git status --porcelain', subDir), execAsync('git rev-list --count @{u}..HEAD', subDir)]);
        case 1:
          _yield$Promise$all = _context.sent;
          _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 2);
          statusOutput = _yield$Promise$all2[0];
          aheadCount = _yield$Promise$all2[1];
          if (statusOutput.trim()) {
            console.log(chalk.red('[not clean] '), subDir);
          }
          count = parseInt(aheadCount.trim(), 10);
          if (count > 0) {
            console.log(chalk.blue('[not push]'), subDir);
          }
        case 2:
        case "end":
          return _context.stop();
      }
    }, _callee);
  }));
}
/**
 * 异步并行检查目录下所有 git 仓库的工作区状态
 * 相比同步版本，在仓库数量较多时有显著的性能提升
 * @param dir - 要检查的父目录路径
 * @example
 * ```ts
 * // 并行检查 ~/Documents/git 下所有子仓库
 * await checkGitClean('/Users/foo/Documents/git');
 * // 控制台会输出：
 * // [not clean]   /Users/foo/Documents/git/repoA
 * // [not push]    /Users/foo/Documents/git/repoB
 * ```
 */
function checkGitClean(dir) {
  return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
    var fs, path, chalk, list, tasks;
    return _regeneratorRuntime.wrap(function (_context2) {
      while (1) switch (_context2.prev = _context2.next) {
        case 0:
          fs = getFs();
          path = getPath();
          chalk = getChalk();
          if (fs.existsSync(dir)) {
            _context2.next = 1;
            break;
          }
          console.error("Not Exist ".concat(dir));
          return _context2.abrupt("return");
        case 1:
          list = fs.readdirSync(dir); // 筛选出所有 git 仓库，并行检查
          tasks = list.map(function (file) {
            return path.resolve(dir, file);
          }).filter(function (subDir) {
            return fs.existsSync(path.resolve(subDir, '.git'));
          }).map(function (subDir) {
            return checkSingleRepo(subDir, chalk);
          });
          _context2.next = 2;
          return Promise.all(tasks);
        case 2:
        case "end":
          return _context2.stop();
      }
    }, _callee2);
  }));
}
/**
 * 同步版本，保持向后兼容
 * @param dir - 要检查的父目录路径
 * @example
 * ```ts
 * checkGitCleanSync('/Users/foo/Documents/git');
 * // 同步依次检查，仓库有变动或未推送会打印警告
 * ```
 */
function checkGitCleanSync(dir) {
  var fs = getFs();
  var path = getPath();
  var chalk = getChalk();
  if (!fs.existsSync(dir)) {
    console.error("Not Exist ".concat(dir));
    return;
  }
  var list = fs.readdirSync(dir);
  list.forEach(function (file) {
    var subDir = path.resolve(dir, file);
    var dotGit = path.resolve(subDir, '.git');
    var isGitRepo = fs.existsSync(dotGit);
    if (isGitRepo) {
      var statusOutput = execCommand('git status --porcelain', subDir, 'pipe');
      if (statusOutput.trim()) {
        console.log(chalk.red('[not clean] '), subDir);
      }
      var aheadCount = execCommand('git rev-list --count @{u}..HEAD 2>/dev/null || echo 0', subDir, 'pipe');
      if (aheadCount.trim() && parseInt(aheadCount.trim(), 10) > 0) {
        console.log(chalk.blue('[not push]'), subDir);
      }
    }
  });
}

export { checkGitClean, checkGitCleanSync };
