const fs = require('fs');
const path = require('path');
const rollup = require('rollup');
const babel = require('@rollup/plugin-babel');
const terser = require('@rollup/plugin-terser');

const babelPlugin = babel.babel || babel.default || babel;
const terserPlugin = terser.terser || terser.default || terser;

const entries = [
	{ input: 'src/index.js', name: 'preact', file: 'dist/preact' },
	{
		input: 'hooks/src/index.js',
		name: 'preactHooks',
		file: 'hooks/dist/hooks',
		external: ['preact']
	},
	{
		input: 'compat/src/index.js',
		name: 'preactCompat',
		file: 'compat/dist/compat',
		external: ['preact', 'preact/hooks']
	},
	{
		input: 'debug/src/index.js',
		name: 'preactDebug',
		file: 'debug/dist/debug',
		external: ['preact', 'preact/devtools']
	},
	{
		input: 'devtools/src/index.js',
		name: 'preactDevtools',
		file: 'devtools/dist/devtools',
		external: ['preact']
	},
	{
		input: 'test-utils/src/index.js',
		name: 'preactTestUtils',
		file: 'test-utils/dist/testUtils',
		external: ['preact']
	},
	{
		input: 'jsx-runtime/src/index.js',
		name: 'jsxRuntime',
		file: 'jsx-runtime/dist/jsxRuntime',
		external: ['preact']
	}
];

const globals = {
	preact: 'preact',
	'preact/hooks': 'preactHooks',
	'preact/devtools': 'preactDevtools'
};

function plugins(extra = []) {
	return [
		babelPlugin({
			babelHelpers: 'bundled',
			babelrc: false,
			configFile: false,
			extensions: ['.js'],
			presets: [
				[
					require.resolve('@babel/preset-env'),
					{
						loose: true,
						modules: false,
						exclude: ['@babel/plugin-transform-typeof-symbol'],
						targets: { browsers: ['last 2 versions', 'IE >= 9'] }
					}
				]
			],
			plugins: [require.resolve('@babel/plugin-transform-react-jsx')]
		}),
		...extra
	];
}

async function buildEntry(entry) {
	fs.mkdirSync(path.dirname(entry.file), { recursive: true });

	const bundle = await rollup.rollup({
		input: entry.input,
		external: entry.external || [],
		plugins: plugins()
	});

	await bundle.write({
		file: `${entry.file}.js`,
		format: 'cjs',
		exports: 'named',
		sourcemap: true
	});
	await bundle.write({
		file: `${entry.file}.module.js`,
		format: 'esm',
		sourcemap: true
	});
	await bundle.write({
		file: `${entry.file}.umd.js`,
		format: 'umd',
		name: entry.name,
		globals,
		exports: 'named',
		sourcemap: true
	});
	await bundle.close();

	fs.copyFileSync(`${entry.file}.module.js`, `${entry.file}.mjs`);
}

async function buildMinifiedCore() {
	const bundle = await rollup.rollup({
		input: 'src/cjs.js',
		plugins: plugins([terserPlugin()])
	});

	await bundle.write({
		file: 'dist/preact.min.js',
		format: 'iife',
		name: 'preact',
		sourcemap: true
	});
	await bundle.close();
}

async function main() {
	for (const entry of entries) {
		await buildEntry(entry);
	}
	await buildMinifiedCore();
}

main().catch(error => {
	console.error(error);
	process.exit(1);
});
