import { readdir } from 'fs';
import path from 'path';
import { promisify } from 'util';

import del from 'del';
import camelCase from 'camelcase';
import replace from '@rollup/plugin-replace';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import json from '@rollup/plugin-json';
import babel from 'rollup-plugin-babel';
import { terser } from 'rollup-plugin-terser';
import filesize from 'rollup-plugin-filesize';

import babelConfig from './babel.config.json';

const readDir = promisify(readdir);

const PACKAGES_DIR = path.join(process.cwd(), 'packages');

const builds = {
  modern: [{ format: 'es' }],
  legacy: [
    { format: 'cjs' },
    { format: 'amd' },
    { format: 'umd' },
    { format: 'umd', minify: true },
  ],
};

const globals = {
  autotyper: 'autotyper',
  'component-emitter': 'Emitter',
  jquery: 'jQuery',
};

const getPlugins = buildType =>
  [
    replace({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
    }),

    json({
      exclude: 'node_modules/**',
      preferConst: true,
    }),

    buildType !== 'modern' &&
      babel({
        babelrc: false,
        exclude: 'node_modules/**',
        ...babelConfig,
      }),

    resolve(),

    commonjs(),
  ].filter(Boolean);

const getBuildPlugins = minify => [
  minify
    ? terser()
    : terser({
        mangle: false,
        compress: false,
        output: {
          beautify: true,
          indent_level: 2,
        },
      }),
  filesize(),
];

const getFilename = (format, minify) => {
  const parts = ['index'];

  if (!minify && format !== 'cjs') {
    parts.push(format);
  }

  if (minify) {
    parts.push('min');
  }

  parts.push('js');

  return parts.join('.');
};

export default async () => {
  const packageNames = await readDir(PACKAGES_DIR);

  const configs = await Promise.all(
    packageNames.map(async name => {
      const dir = path.join(PACKAGES_DIR, name);
      const manifestPath = path.join(dir, 'package.json');
      const { dependencies, peerDependencies = {} } = require(manifestPath);
      const input = path.join(dir, 'src/index.js');
      const outputDir = path.join(dir, 'dist');

      await del(`${outputDir}/*`);

      return Object.entries(builds).map(([buildType, outputs]) => ({
        input,

        plugins: getPlugins(buildType),

        external: [
          ...Object.keys(dependencies),
          ...Object.keys(peerDependencies),
        ],

        output: outputs.map(({ format, minify }) => ({
          file: path.join(outputDir, getFilename(format, minify)),
          format,
          name: camelCase(name),
          sourcemap: minify,
          globals,
          exports: 'named',

          plugins: getBuildPlugins(minify),
        })),
      }));
    }),
  );

  return configs.flat();
};

@@ -665,21 +665,16 @@
 egacy: %5B
-%0A    
 %7B format
@@ -679,28 +679,24 @@
 at: 'cjs' %7D,
-%0A   
  %7B format: '
@@ -698,28 +698,24 @@
 at: 'amd' %7D,
-%0A   
  %7B format: '
@@ -720,22 +720,31 @@
  'umd' %7D
+%5D
 ,%0A  
-  
+browser: %5B
 %7B format
@@ -766,20 +766,16 @@
 : true %7D
-,%0A  
 %5D,%0A%7D;%0A%0Ac
@@ -1738,16 +1738,244 @@
 ');%0A%7D;%0A%0A
+const getExternal = (buildType, dependencies, peerDependencies) =%3E %7B%0A  if (buildType === 'browser') %7B%0A    return Object.keys(peerDependencies);%0A  %7D%0A%0A  return %5B...Object.keys(dependencies), ...Object.keys(peerDependencies)%5D;%0A%7D;%0A%0A
 export d
@@ -2592,75 +2592,45 @@
 al: 
-%5B%0A          ...Object.keys(dependencies),%0A          ...Object.keys(
+getExternal(buildType, dependencies, 
 peer
@@ -2647,19 +2647,8 @@
 es),
-%0A        %5D,
 %0A%0A  

add `browser` build type