const path = require('path');
const os = require('os');

const { mkdir, readdir, copyFile, stat } = require('fs').promises;

function toPascalCase(string) {
  return `${string}`
    .toLowerCase()
    .replace(new RegExp(/[-_]+/, 'g'), ' ')
    .replace(new RegExp(/[^\w\s]/, 'g'), '')
    .replace(new RegExp(/\s+(.)(\w*)/, 'g'), ($1, $2, $3) => `${$2.toUpperCase() + $3}`)
    .replace(new RegExp(/\w/), (s) => s.toUpperCase());
}

function slash(p) {
  return p.replace(/\\/g, '/');
}

const cleanUrl = (url) => {
  const QUERY_RE = /\?.*$/s;
  const HASH_RE = /#.*$/s;
  return url.replace(HASH_RE, '').replace(QUERY_RE, '');
};

function normalizePath(id) {
  const isWindows = os.platform() === 'win32';
  return path.posix.normalize(isWindows ? slash(id) : id);
}

const fileExists = async (path) => !!(await stat(path).catch((e) => false));

async function copyFolder(src, dest, filter) {
  if (!(await fileExists(dest))) {
    await mkdir(dest);
  }
  const entries = await readdir(src);
  return Promise.all(
    entries.map(async (entry) => {
      const srcPath = path.join(src, entry);
      if (filter(srcPath)) {
        const destPath = path.join(dest, entry);
        const _stat = await stat(srcPath);
        if (_stat.isFile()) {
          copyFile(srcPath, destPath);
        } else if (_stat.isDirectory()) {
          copyFolder(srcPath, destPath, filter);
        }
      }
    }),
  );
}
module.exports = { toPascalCase, cleanUrl, normalizePath, copyFolder };
