'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var node_nodeCommand = require('../node/node-command.js');
var nodejs_os = require('../nodejs/os.js');
var thirdParty_logSymbols = require('../third-party/log-symbols.js');
var syncRepo_helper = require('./helper.js');
require('@babel/runtime/helpers/typeof');
require('../nodejs/child_process.js');

function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
/**
 * 转义字符串中的特殊字符
 * 将斜杠和双引号转义，用于 sed 命令
 * @param str - 要转义的字符串
 * @returns 转义后的字符串
 * @private
 */
function transformString() {
  var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  return str.replace(/(\/|")/g, '\\$1');
}
/**
 * 合并同一 dirList 下的多条替换规则，减少 grep 扫描次数
 * @param replaceList - 替换配置列表
 * @returns 合并后的替换配置列表
 * @private
 */
function mergeReplaceList(replaceList) {
  var dirKeyMap = new Map();
  var result = [];
  var _iterator = _createForOfIteratorHelper(replaceList),
    _step;
  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var item = _step.value;
      var dirList = item.dirList,
        to = item.to,
        from = item.from,
        list = item.list;
      var newDir = Array.isArray(dirList) ? dirList : [dirList];
      if (!(newDir === null || newDir === void 0 ? void 0 : newDir.length)) continue;
      var dirKey = JSON.stringify(newDir.slice().sort());
      if (list === null || list === void 0 ? void 0 : list.length) {
        // list 模式，合并到同一个 dirKey 下
        if (!dirKeyMap.has(dirKey)) {
          dirKeyMap.set(dirKey, {
            list: [],
            dirList: newDir
          });
        }
        var entry = dirKeyMap.get(dirKey);
        var _iterator2 = _createForOfIteratorHelper(list),
          _step2;
        try {
          for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
            var inner = _step2.value;
            entry.list.push([inner[0], inner[1]]);
          }
        } catch (err) {
          _iterator2.e(err);
        } finally {
          _iterator2.f();
        }
        continue;
      }
      if (!from) continue;
      // from/to 模式，也合并到同一个 dirKey 下
      if (!dirKeyMap.has(dirKey)) {
        dirKeyMap.set(dirKey, {
          list: [],
          dirList: newDir
        });
      }
      dirKeyMap.get(dirKey).list.push([from, to || '']);
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }
  dirKeyMap.forEach(function (entry) {
    result.push({
      list: entry.list,
      dirList: entry.dirList
    });
  });
  return result;
}
/**
 * 替换文件内容
 * 批量替换目标项目中指定文件的内容
 * @param replaceList - 替换配置列表
 * @param targetProject - 目标项目路径
 * @example
 * ```ts
 * replaceContent({
 *   replaceList: [
 *     {
 *       dirList: ['src/*.ts'],
 *       from: 'old-text',
 *       to: 'new-text'
 *     }
 *   ],
 *   targetProject: '/path/to/project'
 * });
 * ```
 */
function replaceContent(_ref) {
  var replaceList = _ref.replaceList,
    targetProject = _ref.targetProject;
  var mergedList = mergeReplaceList(replaceList);
  var _iterator3 = _createForOfIteratorHelper(mergedList),
    _step3;
  try {
    var _loop = function _loop() {
        var item = _step3.value;
        var dirList = item.dirList,
          list = item.list;
        var newDir = Array.isArray(dirList) ? dirList : [dirList];
        if (!(newDir === null || newDir === void 0 ? void 0 : newDir.length)) return 0; // continue
        if (list === null || list === void 0 ? void 0 : list.length) {
          syncRepo_helper.checkValidReplaceList(list);
          list.forEach(function (inner) {
            replaceEachContent({
              dirList: newDir,
              to: transformString(inner[1]),
              from: transformString(inner[0]),
              targetProject: targetProject
            });
          });
          return 0; // continue
        }
      },
      _ret;
    for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
      _ret = _loop();
      if (_ret === 0) continue;
    }
  } catch (err) {
    _iterator3.e(err);
  } finally {
    _iterator3.f();
  }
}
/**
 * 在目标项目中执行命令
 * @param command - 要执行的命令
 * @param targetProject - 目标项目路径
 * @example
 * ```ts
 * execCommandInTarget('npm install', '/path/to/project');
 * ```
 */
function execCommandInTarget(command, targetProject) {
  node_nodeCommand.execCommand(command, targetProject, 'inherit');
}
/**
 * 替换单个内容
 * 在指定目录列表中替换文件内容
 * @param dirList - 目录列表
 * @param to - 替换为的内容
 * @param from - 要被替换的内容
 * @param targetProject - 目标项目路径
 * @example
 * ```ts
 * replaceEachContent({
 *   dirList: ['src', 'lib'],
 *   from: '@old/package',
 *   to: '@new/package',
 *   targetProject: '/path/to/project'
 * });
 * ```
 */
function replaceEachContent(_ref2) {
  var dirList = _ref2.dirList,
    to = _ref2.to,
    from = _ref2.from,
    targetProject = _ref2.targetProject;
  var _iterator4 = _createForOfIteratorHelper(dirList),
    _step4;
  try {
    for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
      var dir = _step4.value;
      try {
        // sed -i "" 's/@xxx\/press-ui/press-ui/g' README.md
        // find . | xargs grep string # 查找当前目录下文件内容包含字符串string的文件
        // 报错：RE error: illegal byte sequence'
        // 解决办法：export LC_COLLATE='C'
        // export LC_CTYPE='C'
        // 参考：https://blog.csdn.net/wqhjfree/article/details/39032533
        log("\u6B63\u5728\u66FF\u6362 ".concat(from, " to ").concat(to));
        var platform = nodejs_os.getOs().platform();
        var keyword = platform === 'linux' ? '-i' : '-i \'\'';
        var command = "sed ".concat(keyword, " \"s/").concat(from, "/").concat(to, "/g\" `grep -rl \"").concat(from, "\" ").concat(dir, "`  || true");
        execCommandInTarget(command, targetProject);
      } catch (err) {
        console.log('replaceEachContent.err', err);
      }
    }
  } catch (err) {
    _iterator4.e(err);
  } finally {
    _iterator4.f();
  }
}
/**
 * 输出日志信息
 * 带有信息图标的日志输出
 * @param content - 日志内容
 * @param args - 额外参数
 * @example
 * ```ts
 * log('正在处理...', 'file.ts');
 * ```
 */
function log(content) {
  var _console;
  var symbols = thirdParty_logSymbols.getLogSymbols();
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    args[_key - 1] = arguments[_key];
  }
  (_console = console).log.apply(_console, ["".concat(symbols.info, " ").concat(content)].concat(args));
}

exports.execCommandInTarget = execCommandInTarget;
exports.log = log;
exports.replaceContent = replaceContent;
exports.replaceEachContent = replaceEachContent;
