import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
import { writeFileSync, readFileSync } from './fs.mjs';
import { getFs } from '../nodejs/fs.mjs';
import { getPath } from '../nodejs/path.mjs';
import { timeStampFormat } from '../time/time.mjs';
import '../nodejs/crypto.mjs';
import '../nodejs/os.mjs';

var LOG_DIR = 'log';
/**
 * 内部复制函数，用于复制文件和目录
 * @param src - 源路径
 * @param dist - 目标路径
 * @private
 */
function innerCopy(src, dist) {
  // statSync 的结果除了 isFile() 和 isDirectory()，还可能是
  //  符号链接（symlink）、块设备、字符设备、FIFO 等
  if (!getFs().statSync(src).isDirectory()) {
    return;
  }
  var paths = getFs().readdirSync(src);
  paths.forEach(function (p) {
    var tSrc = "".concat(src, "/").concat(p);
    var tDist = "".concat(dist, "/").concat(p);
    var stat = getFs().statSync(tSrc);
    if (stat.isFile()) {
      // 判断是文件还是目录
      writeFileSync(tDist, readFileSync(tSrc));
    } else if (stat.isDirectory()) {
      innerCopyDir(tSrc, tDist); // 当是目录时，递归复制
    }
  });
}
/**
 * 内部递归复制目录函数
 * 复制目录、子目录，及其中的文件
 * @param src - 要复制的源目录路径
 * @param dist - 复制到的目标目录路径
 * @private
 */
function innerCopyDir(src, dist) {
  var b = getFs().existsSync(dist);
  if (!b) {
    mkDirsSync(dist); // 创建目录
  }
  innerCopy(src, dist);
}
/**
 * 递归创建目录（同步方法）
 * 如果目录已存在则直接返回，否则递归创建父目录
 * @param dirname - 要创建的目录路径
 * @returns 创建成功返回 true
 * @example
 * ```ts
 * mkDirsSync('/path/to/new/directory');
 * ```
 */
function mkDirsSync(dirname) {
  if (getFs().existsSync(dirname)) {
    return true;
  }
  if (mkDirsSync(getPath().dirname(dirname))) {
    getFs().mkdirSync(dirname);
    return true;
  }
  return false;
}
/**
 * 拷贝目录以及子文件
 * 递归复制整个目录结构，包括所有子目录和文件
 * @param src - 源目录路径
 * @param dist - 目标目录路径
 * @param callback - 可选的回调函数，复制完成后执行
 * @example
 * ```ts
 * copyDir('/source/path', '/target/path', () => {
 *   console.log('复制完成');
 * });
 * ```
 */
function copyDir(src, dist, callback) {
  innerCopyDir(src, dist);
  if (callback) {
    callback();
  }
}
/**
 * 删除目录及其所有内容
 * 递归删除目录下的所有文件和子目录
 * @param tPath - 要删除的目录路径
 * @example
 * ```ts
 * deleteFolder('/path/to/folder');
 * ```
 */
function deleteFolder(tPath) {
  var files = [];
  if (getFs().existsSync(tPath)) {
    files = getFs().readdirSync(tPath);
    files.forEach(function (file) {
      var curPath = "".concat(tPath, "/").concat(file);
      if (getFs().statSync(curPath).isDirectory()) {
        deleteFolder(curPath);
      } else {
        getFs().unlinkSync(curPath);
      }
    });
    getFs().rmdirSync(tPath);
  }
}
/**
 * 递归删除空目录
 * 从指定路径开始，递归删除所有空目录（不删除包含文件的目录）
 * @param tPath - 要检查和删除的目录路径
 * @param level - 当前递归层级，默认为 0（根层级不会被删除）
 * @example
 * ```ts
 * rmEmptyDir('/path/to/check');
 * ```
 */
function rmEmptyDir(tPath) {
  var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  var files = getFs().readdirSync(tPath);
  if (files.length > 0) {
    var tempFile = 0;
    files.forEach(function (file) {
      tempFile += 1;
      rmEmptyDir("".concat(tPath, "/").concat(file), level + 1);
    });
    if (tempFile === files.length && level !== 0) {
      getFs().rmdirSync(tPath);
    }
  } else {
    level !== 0 && getFs().rmdirSync(tPath);
  }
}
/**
 * 递归删除文件夹（可配置是否删除文件）
 * 递归遍历目录，根据配置决定是否删除文件，并删除空目录
 * @param path - 要处理的目录路径
 * @param options - 配置选项
 * @param options.deleteFile - 是否删除文件，默认为 false
 * @param options.log - 是否输出日志，默认为 false
 * @example
 * ```ts
 * // 只删除空目录
 * deleteFolderRecursive('/path/to/folder');
 *
 * // 删除所有文件和目录
 * deleteFolderRecursive('/path/to/folder', { deleteFile: true, log: true });
 * ```
 */
function deleteFolderRecursive(path) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
    deleteFile: false,
    log: false
  };
  var _a, _b;
  var deleteFile = (_a = options.deleteFile) !== null && _a !== void 0 ? _a : false;
  var log = (_b = options.log) !== null && _b !== void 0 ? _b : false;
  if (getFs().existsSync(path)) {
    var list = getFs().readdirSync(path);
    list.forEach(function (file) {
      var curPath = "".concat(path, "/").concat(file);
      if (getFs().statSync(curPath).isDirectory()) {
        // recurse
        deleteFolderRecursive(curPath, options);
      } else {
        // delete file
        if (deleteFile) {
          getFs().unlinkSync(curPath);
        }
      }
    });
    var remaining = getFs().readdirSync(path);
    if (!remaining.length) {
      if (log) {
        console.log('>>> delete: ', path);
      }
      getFs().rmdirSync(path);
    }
  }
}
/**
 * 拷贝单个文件
 * 将文件从源路径复制到目标路径
 * @param from - 源文件路径
 * @param to - 目标文件路径
 * @returns 写入操作的结果
 * @example
 * ```ts
 * copyFile('/source/file.txt', '/target/file.txt');
 * ```
 */
function copyFile(from, to) {
  return writeFileSync(to, readFileSync(from));
}
/**
 * 递归遍历文件夹，并对每个文件执行回调函数
 * 遍历目录树，对每个文件（非目录）执行指定的回调函数
 * @param cb - 回调函数，接收文件路径作为参数
 * @param tPath - 要遍历的文件夹或文件路径
 * @example
 * ```ts
 * traverseFolder((filePath) => {
 *   console.log('处理文件:', filePath);
 * }, '/path/to/folder');
 * ```
 */
function traverseFolder(cb, tPath) {
  if (getFs().statSync(tPath).isDirectory()) {
    var files = getFs().readdirSync(tPath);
    files.forEach(function (file) {
      var curPath = getPath().resolve(tPath, file);
      // `${tPath}/${file}`;
      traverseFolder(cb, curPath);
    });
  } else {
    cb(tPath);
  }
}
/**
 * 从日志目录读取 JSON 文件
 * 读取 ./log 目录下的 JSON 文件内容
 * @param file - 文件名（相对于 log 目录）
 * @param defaultContent - 文件不存在时返回的默认内容，默认为 '{}'
 * @returns JSON 文件内容字符串
 * @example
 * ```ts
 * const content = readJsonLog('data.json', '[]');
 * ```
 */
function readJsonLog(file) {
  var defaultContent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '{}';
  var filePath = "./".concat(LOG_DIR, "/").concat(file);
  if (!getFs().existsSync(filePath)) {
    createLogDir();
    return defaultContent;
  }
  return readFileSync(filePath) || defaultContent;
}
/**
 * 获取 JSON 日志目录的绝对路径
 * @returns 日志目录的绝对路径
 * @example
 * ```ts
 * const logDir = getJsonLogDir();
 * console.log(logDir); // /path/to/project/log
 * ```
 */
function getJsonLogDir() {
  return getPath().resolve(process.cwd(), './log');
}
/**
 * 将 JSON 对象保存到日志文件
 * 将对象序列化为 JSON 并保存到 ./log 目录下
 * @param content - 要保存的对象内容
 * @param file - 文件名（相对于 log 目录）
 * @param needLog - 是否需要保存日志，默认为 true
 * @example
 * ```ts
 * saveJsonToLog({ status: 'success', data: [1, 2, 3] }, 'result.json');
 * ```
 */
function saveJsonToLog(content, file) {
  var needLog = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  if (!needLog) return;
  createLogDir();
  writeFileSync("./".concat(LOG_DIR, "/").concat(file), content, true);
}
/**
 * 将内容追加保存到日志文件（支持保留历史记录）
 * 以数组形式保存多条日志记录，每条记录包含时间戳和数据，支持限制最大记录数
 * @param content - 要保存的内容
 * @param file - 文件名（相对于 log 目录）
 * @param options - 配置选项
 * @param options.needLog - 是否需要保存日志，默认为 true
 * @param options.max - 最大保留记录数，默认为 10
 * @example
 * ```ts
 * saveJsonToLogMore({ action: 'upload', status: 'success' }, 'history.json', {
 *   needLog: true,
 *   max: 20
 * });
 * ```
 */
function saveJsonToLogMore(content, file, options) {
  var _a, _b;
  var needLog = (_a = options === null || options === void 0 ? void 0 : options.needLog) !== null && _a !== void 0 ? _a : true;
  var max = (_b = options === null || options === void 0 ? void 0 : options.max) !== null && _b !== void 0 ? _b : 10;
  if (!needLog) return;
  createLogDir();
  var filePath = "./log/".concat(file);
  var beforeContent = [];
  var newContent = [{
    logTime: timeStampFormat(Date.now(), 'yyyy-MM-dd hh:mm:ss'),
    data: content
  }];
  if (getFs().existsSync(filePath)) {
    try {
      beforeContent = readFileSync(filePath, true).logList || [];
    } catch (err) {
      beforeContent = [];
    }
  }
  if (beforeContent && Array.isArray(beforeContent)) {
    var _newContent;
    (_newContent = newContent).push.apply(_newContent, _toConsumableArray(beforeContent));
  }
  newContent = newContent.slice(0, max);
  try {
    getFs().writeFile(filePath, JSON.stringify({
      logList: newContent
    }, null, 2), {
      encoding: 'utf-8'
    }, function () {});
  } catch (err) {}
}
/**
 * 从日志目录读取并解析 JSON 文件
 * 读取 ./log 目录下的 JSON 文件并解析为对象
 * @param file - 文件名（相对于 log 目录）
 * @returns 解析后的 JSON 对象，解析失败或文件不存在时返回空对象
 * @example
 * ```ts
 * const data = getJsonFromLog('config.json');
 * console.log(data);
 * ```
 */
function getJsonFromLog(file) {
  var filePath = "./".concat(LOG_DIR, "/").concat(file);
  var data = {};
  if (!getFs().existsSync(filePath)) {
    console.log('[getJsonFromLog] no exist');
  } else {
    var originFile = getFs().readFileSync(filePath, {
      encoding: 'utf-8'
    });
    try {
      data = JSON.parse(originFile);
    } catch (err) {}
  }
  return data;
}
/**
 * 创建日志目录
 * 如果 ./log 目录不存在则创建
 * @private
 */
function createLogDir() {
  if (!getFs().existsSync("./".concat(LOG_DIR))) {
    getFs().mkdirSync("./".concat(LOG_DIR));
  }
}
/**
 * 从文件路径中提取文件名（不含扩展名）
 * @param file - 文件路径
 * @returns 不含扩展名的文件名
 * @example
 * ```ts
 * const name = getFileName('/path/to/file.txt');
 * console.log(name); // 'file'
 * ```
 */
function getFileName(file) {
  var basename = getPath().basename(file);
  var extname = getPath().extname(file);
  var fileName = basename.replace(new RegExp("".concat(extname, "$")), '');
  return fileName;
}
/**
 * 解析 JSON 字符串为对象
 * 安全地解析 JSON 字符串，解析失败时输出错误信息并返回空对象
 * @param content - JSON 字符串内容
 * @param file - 文件路径（用于错误日志）
 * @returns 解析后的对象，解析失败时返回空对象
 * @example
 * ```ts
 * const data = readJson('{"name":"test"}', 'config.json');
 * console.log(data); // { name: 'test' }
 * ```
 */
function readJson(content, file) {
  var data = {};
  try {
    data = JSON.parse(content);
  } catch (e) {
    console.error('>>> read json error: ', file);
  }
  return data;
}

export { copyDir, copyFile, deleteFolder, deleteFolderRecursive, getFileName, getJsonFromLog, getJsonLogDir, mkDirsSync, readJson, readJsonLog, rmEmptyDir, saveJsonToLog, saveJsonToLogMore, traverseFolder };
