import fs from 'fs';
import archiver from 'archiver';
import { exec } from 'child_process';
import { readdir, stat } from 'fs/promises';

export function readFileRange(file, start, length) {
  return new Promise((resolve, reject) => {
    fs.open(file, 'r', (err, fd) => {
      if (err) {
        reject('Error opening file:', er);
        return;
      }
      const buffer = Buffer.alloc(length);
      fs.read(fd, buffer, 0, length, start, (err, bytesRead, buffer) => {
        if (err) {
          reject('Error reading file:', err)
          return;
        }
        fs.close(fd, (err) => {
          if (err) {
            reject('Error closing file:', err)
            return ;
          }
          resolve(buffer);
        });
      });
    });
  })
  
}
export function pad(num, n) {
  var strNum = num.toString();
  var len = strNum.length;
  while (len < n) {
    strNum = "0" + strNum;
    len++;
  }
  return strNum;
}
export function execAsync(command) {
  return new Promise((resolve, reject) => {
    console.log('[CMD] ' + command);
    exec(command, (error, stdout, stderr) => {
      if (error) {
        reject(error);
        return;
      }
      resolve(stdout);
    });
  })
}
export async function compressZip(dir, targetFilePath, skipFiles) {
  const output = fs.createWriteStream(targetFilePath);
  const archive = archiver('zip', {
    zlib: { level: 9 } // Sets the compression level.
  });
  archive.pipe(output);

  function checkPathSkip(pathString) {
    if (!pathString)
      return true;
    if (pathString.startsWith('.') || pathString.startsWith('/.'))
      return true;
    if (!skipFiles || skipFiles.length === 0)
      return;
    return skipFiles.find((item) => pathString.startsWith(item) || pathString.startsWith(`/${item}`));
  }

  async function loopDir(path, subPrefix) {
    const files = await readdir(path);
    for (const file of files) {
      const subPath = subPrefix + '/' + file;
      if (checkPathSkip(subPath))
        continue;
      console.log('File: ' + subPath);
      const filestat = await stat(dir + subPath);
      if (filestat.isDirectory()) {
        await loopDir(dir + subPath, subPath);
      } else {
        archive.file(dir + subPath, { name: subPath });
      }
    }
  }
  await loopDir(dir, '')

  console.log('等待压缩zip...');

  const waitArchive = new Promise((resolve, reject) => {
    output.on('close', function() {
      console.log(archive.pointer() + ' total bytes');
      console.log('archiver has been finalized and the output file descriptor has closed.');
      resolve();
    });
    archive.on('error', function(err) {
      reject(err);
    });
  })

  await archive.finalize();
  await waitArchive;
}