const fs = require('fs');
const path = require('path');
const chalk = require('chalk');

const configFileName = 'kt.vue3.i18n.generator.config.js';

const isRegExp = val =>
  Object.prototype.toString.call(val) === '[object RegExp]';

const findExisting = (context, files) => {
  for (const file of files) {
    if (fs.existsSync(path.join(context, file))) {
      return file;
    }
  }
};

let generatorBlackList = [];
/**
 * 获取项目根目录下的配置文件
 */
const getConfig = () => {
  const hasConfig = !!findExisting('.', [configFileName]);
  if (hasConfig) {
    const config = require(path.join(process.cwd(), configFileName));
    if (
      config.generatorBlackList &&
      Array.isArray(config.generatorBlackList) &&
      config.generatorBlackList.length > 0
    ) {
      generatorBlackList = config.generatorBlackList;
    }
  }
};

/**
 * 过滤需要操作的文件，需要返回 true 才会被加入可操作文件数组
 * 白名单后缀
 * '.vue', '.js', '.ts'
 *
 * 黑名单
 * - .d.ts
 * - router/*
 * - locale/*
 */
const filter = name => {
  name = name.toLowerCase();
  // [\\/]
  const blackList = [
    // 正则模糊匹配
    /\.d\.ts$/,
    /[\\/]locale[\\/]/,
    // 手动维护 router 相关
    /[\\/]router[\\/]/
  ];

  const pick = name => ['.vue', '.js', '.ts'].indexOf(path.extname(name)) > -1;

  const omit = name => {
    const res = [...blackList, ...generatorBlackList].map(c => {
      // 正则
      if (isRegExp(c)) return !c.test(name);
      // 字符串
      else if (name.indexOf(`${c}`.toLowerCase()) > -1) return false;
      return true;
    });
    // 结果没有全票通过，返回 false
    return !res.includes(false);
  };
  return pick(name) && omit(name);
};

/**
 * 获取所有满足需求的文件
 */
const getAllFiles = dir => {
  let results = [];
  fs.readdirSync(dir).forEach(item => {
    item = path.join(dir, item);
    if (fs.lstatSync(item).isDirectory()) {
      results.push(...getAllFiles(item));
    } else {
      if (filter(item)) {
        results.push(item);
      }
    }
  });
  return results;
};

/**
 * 获取单个满足需求的文件
 */
const getFile = files => {
  let results = [];
  for (const item of files) {
    if (filter(item)) {
      results.push(item);
    }
  }
  return results;
};

const showTips = () => {
  console.log(chalk.bgGray('tips：[G]生成，[R]恢复，文件名置灰表示没有更改\n'));
};
exports.getAllFiles = getAllFiles;

exports.getFile = getFile;

exports.getConfig = getConfig;

exports.showTips = showTips;
