const path = require('path');
const { merge } = require('webpack-merge');
const wpScriptsConfig = require('@wordpress/scripts/config/webpack.config');
const version = require('./package.json').version;
const { ProvidePlugin } = require('webpack');
const TerserPlugin = require( 'terser-webpack-plugin' );

/**
 * Aliases for resolving Brand imports
 */
const alias = {
    App: path.resolve(__dirname, '/src/app/'),
	Assets: path.resolve( __dirname, '/assets/' ),
    Store: path.resolve(__dirname, '/src/app/data/store.js'),
    Routes: path.resolve(__dirname, '/src/app/data/routes.js'),
    '@modules': path.resolve( __dirname, '/vendor/newfold-labs/' ),
};
/**
 * Make most-common imports available globally to ease import debt.
 * (Instead of import { useEffect } from '@wordpress/element' in every file)
 */
const mostCommonImports = {
    Fragment: ['@wordpress/element', 'Fragment'],
    useState: ['@wordpress/element', 'useState'],
    useEffect: ['@wordpress/element', 'useEffect'],
    useContext: ['@wordpress/element', 'useContext'],
    useLocation: ['react-router-dom', 'useLocation'],
    useNavigate: ['react-router-dom', 'useNavigate'],
    _filter: ['lodash', 'filter'],
    _map: ['lodash', 'map'],
    _isEmpty: ['lodash', 'isEmpty'],
    _camelCase: ['lodash', 'camelCase'],
    __: ['@wordpress/i18n', '__'],
    _n: ['@wordpress/i18n', '_n'],
    sprintf: ['@wordpress/i18n', 'sprintf'],
    classNames: ['classnames'],
};

/**
 * Terser's function to decide which comments to preserve.
 *
 * @see https://github.com/Automattic/jetpack/blob/fdf3b72390c7fcb64508d985149de2af01b935b3/projects/js-packages/webpack-config/src/webpack/terser.js
 * @see https://github.com/terser/terser/blob/v5.9.0/lib/output.js#L171-L177
 * @param {object} comment - Comment object.
 * @param {string} comment.type - Comment type.
 * @param {string} comment.value - Comment text.
 * @returns {boolean} Whether to keep it.
 */
 function isSomeComments( comment ) {
	return (
		( comment.type === 'comment2' || comment.type === 'comment1' ) &&
		/@preserve|@lic|@cc_on|^\**!/i.test( comment.value )
	);
}

/**
 * Function to match a WP i18n "translators" comment.
 *
 * @see https://github.com/Automattic/jetpack/blob/fdf3b72390c7fcb64508d985149de2af01b935b3/projects/js-packages/webpack-config/src/webpack/terser.js
 * @see https://github.com/php-gettext/Gettext/blob/4.x/src/Utils/ParsedComment.php#L53-L73
 * @see https://github.com/wp-cli/i18n-command/blob/v2.2.9/src/JsCodeExtractor.php#L15
 * @param {object} comment - Comment object.
 * @param {string} comment.type - Comment type.
 * @param {string} comment.value - Comment text.
 * @returns {boolean} Whether to keep it.
 */
 function isTranslatorsComment( comment ) {
	return (
		( comment.type === 'comment2' || comment.type === 'comment1' ) &&
		/^[#*/ \t\r\n]*[tT]ranslators/.test( comment.value )
	);
}

/**
 * Extend @wordpress/scripts default webpack config with:
 * - Versioned build folder (via package.json version) for cache-busting.
 * - Set Plugin-specific aliases for tidy imports.
 * - Use webpack's ProvidePlugin to ease repetitive imports.
 */
const hostgatorConfig = {
    mode: 'production',
    output: {
        // versioned output directory i.e. /build/1.0.0, /build/1.1.0, etc.
        path: path.resolve(process.cwd(), 'build/' + version),
    },
    resolve: { alias },
    plugins: [new ProvidePlugin(mostCommonImports)],
    optimization: {
        concatenateModules: false,
        minimize: true,
        minimizer: [
            new TerserPlugin( {
                terserOptions: {
                    mangle: {
                        reserved: [ '__', '_n', '_nx', '_x' ]
                    },
                    format: {
                        // The `new Function` bit here is a hack to work around the way terser-webpack-plugin serializes
                        // the terserOptions. The "comments" function must not refer to anything from the local or global scope,
                        // so we "paste" our external functions inside.
                        comments: new Function(
                            'node',
                            'comment',
                            `${ isTranslatorsComment }; return isTranslatorsComment( comment )`
                        ),
                    },
                },
                // Same.
                extractComments: new Function(
                    'node',
                    'comment',
                    `${ isSomeComments }; return isSomeComments( comment )`
                ),
            }),
        ]
    },

};
module.exports = merge(wpScriptsConfig, hostgatorConfig);