text: const { camelCase, upperFirst } = require('lodash')
  const { INDEX_FILE_NAME, DEVUI_DIR } = require('./constant')
  const { resolve } = require('path')
  const logger = require('./logger')
  const fs = require('fs-extra')
  const traverse = require("@babel/traverse").default
  const babelParser = require("@babel/parser")
  
  exports.bigCamelCase = (str) => {
    return upperFirst(camelCase(str))
  }
  
  exports.resolveDirFilesInfo = (targetDir, ignoreDirs = []) => {
    return fs
      .readdirSync(targetDir)
      .filter(
        (dir) =>
          // 过滤：必须是目录，且不存在与忽略目录内，拥有 INDEX_FILE_NAME
          fs.statSync(resolve(targetDir, dir)).isDirectory() &&
          !ignoreDirs.includes(dir) &&
          fs.existsSync(resolve(targetDir, dir, INDEX_FILE_NAME))
      )
      .map((dir) => ({
        name: this.bigCamelCase(dir),
        dirname: dir,
        path: resolve(targetDir, dir, INDEX_FILE_NAME)
      }))
  }
  
  exports.parseExportByFileInfo = (fileInfo, ignoreParseError) => {
    const exportModule = {}
    const indexContent = fs.readFileSync(fileInfo.path, { encoding: 'utf-8' })
  
    const ast = babelParser.parse(indexContent, {
      sourceType: 'module',
      plugins: [
        'typescript'
      ]
    })
  
    const exportName = []
    let exportDefault = null
  
    traverse(ast, {
      ExportNamedDeclaration({node}) {
        if (node.specifiers.length) {
          node.specifiers.forEach(specifier => {
            exportName.push(specifier.local.name)
          })
        } else if (node.declaration) {
          if (node.declaration.declarations) {
            node.declaration.declarations.forEach(dec => {
              exportName.push(dec.id.name)
            })
          } else if (node.declaration.id) {
            exportName.push(node.declaration.id.name)
          }
        }
      },
      ExportDefaultDeclaration() {
        exportDefault = fileInfo.name + 'Install'
      }
    })
  
    if (!exportDefault) {
      logger.error(`${fileInfo.path} must have "export default".`)
  
      if (ignoreParseError) {
        return exportModule
      } else {
        process.exit(1)
      }
    }
  
    if (!exportName.length) {
      logger.error(`${fileInfo.path} must have "export xxx".`)
      
      if (ignoreParseError) {
        return exportModule
      } else {
        process.exit(1)
      }
    }
  
    exportModule.default = exportDefault
    exportModule.parts = exportName
    exportModule.fileInfo = fileInfo
  
    return exportModule
  }
  
  exports.parseComponentInfo = (name) => {
    const componentInfo = {
      name: this.bigCamelCase(name)
    }
    let hasExportDefault = false
    const indexContent = fs.readFileSync(resolve(DEVUI_DIR, name, INDEX_FILE_NAME), { encoding: 'utf-8' })
  
    const ast = babelParser.parse(indexContent, {
      sourceType: 'module',
      plugins: [
        'typescript'
      ]
    })
    traverse(ast, {
      ExportDefaultDeclaration({node}) {
        hasExportDefault = true
        if (node.declaration && node.declaration.properties) {
          const properties = node.declaration.properties
          properties.forEach(pro => {
            if (pro.type === 'ObjectProperty') {
              componentInfo[pro.key.name] = pro.value.value
            }
          })
        }
      }
    })
  
    if (!hasExportDefault) {
      logger.warning(`${componentInfo.name} must have "export default" and component info.`)
    }
  
    return componentInfo
  }
  