text: import { bundleMDX } from 'mdx-bundler'
  import fs from 'fs'
  import matter from 'gray-matter'
  import path from 'path'
  import readingTime from 'reading-time'
  import visit from 'unist-util-visit'
  import getAllFilesRecursively from './utils/files'
  
  const root = process.cwd()
  
  const tokenClassNames = {
    tag: 'text-code-red',
    'attr-name': 'text-code-yellow',
    'attr-value': 'text-code-green',
    deleted: 'text-code-red',
    inserted: 'text-code-green',
    punctuation: 'text-code-white',
    keyword: 'text-code-purple',
    string: 'text-code-green',
    function: 'text-code-blue',
    boolean: 'text-code-red',
    comment: 'text-gray-400 italic',
  }
  
  export function getFiles(type) {
    const prefixPaths = path.join(root, 'data', type)
    const files = getAllFilesRecursively(prefixPaths)
    // Only want to return blog/path and ignore root, replace is needed to work on Windows
    return files.map((file) => file.slice(prefixPaths.length + 1).replace(/\\/g, '/'))
  }
  
  export function formatSlug(slug) {
    return slug.replace(/\.(mdx|md)/, '')
  }
  
  export function dateSortDesc(a, b) {
    if (a > b) return -1
    if (a < b) return 1
    return 0
  }
  
  export async function getFileBySlug(type, slug) {
    const mdxPath = path.join(root, 'data', type, `${slug}.mdx`)
    const mdPath = path.join(root, 'data', type, `${slug}.md`)
    const source = fs.existsSync(mdxPath)
      ? fs.readFileSync(mdxPath, 'utf8')
      : fs.readFileSync(mdPath, 'utf8')
  
    // https://github.com/kentcdodds/mdx-bundler#nextjs-esbuild-enoent
    if (process.platform === 'win32') {
      process.env.ESBUILD_BINARY_PATH = path.join(
        process.cwd(),
        'node_modules',
        'esbuild',
        'esbuild.exe'
      )
    } else {
      process.env.ESBUILD_BINARY_PATH = path.join(
        process.cwd(),
        'node_modules',
        'esbuild',
        'bin',
        'esbuild'
      )
    }
  
    let toc = []
  
    const { frontmatter, code } = await bundleMDX(source, {
      // mdx imports can be automatically source from the components directory
      cwd: path.join(process.cwd(), 'components'),
      xdmOptions(options) {
        options.rehypePlugins = [
          ...(options.rehypePlugins ?? []),
          () => {
            return (tree) => {
              visit(tree, 'element', (node, index, parent) => {
                let [token, type] = node.properties.className || []
                if (token === 'token') {
                  node.properties.className = [tokenClassNames[type]]
                }
              })
            }
          },
        ]
        return options
      },
      esbuildOptions: (options) => {
        options.loader = {
          ...options.loader,
          '.js': 'jsx',
        }
        return options
      },
    })
  
    return {
      mdxSource: code,
      toc,
      frontMatter: {
        readingTime: readingTime(code),
        slug: slug || null,
        fileName: fs.existsSync(mdxPath) ? `${slug}.mdx` : `${slug}.md`,
        ...frontmatter,
        date: frontmatter.date ? new Date(frontmatter.date).toISOString() : null,
      },
    }
  }
  
  export async function getAllFilesFrontMatter(folder) {
    const prefixPaths = path.join(root, 'data', folder)
  
    const files = getAllFilesRecursively(prefixPaths)
  
    const allFrontMatter = []
  
    files.forEach((file) => {
      // Replace is needed to work on Windows
      const fileName = file.slice(prefixPaths.length + 1).replace(/\\/g, '/')
      // Remove Unexpected File
      if (path.extname(fileName) !== '.md' && path.extname(fileName) !== '.mdx') {
        return
      }
      const source = fs.readFileSync(file, 'utf8')
      const { data: frontmatter } = matter(source)
      if (frontmatter.draft !== true) {
        allFrontMatter.push({
          ...frontmatter,
          slug: formatSlug(fileName),
          date: frontmatter.date ? new Date(frontmatter.date).toISOString() : null,
        })
      }
    })
  
    return allFrontMatter.sort((a, b) => dateSortDesc(a.date, b.date))
  }
  