const pluginName = 'AsyncChunkSrcVersionParameterPlugin';
/**
 * Inspired by: https://github.com/webpack/webpack/issues/8115#issuecomment-663902035.
 *
 * This plugin modifies the webpack bootstrap code generated by the plugin at
 * webpack/lib/web/JsonpMainTemplatePlugin.js and the CSS chunk loading code generated
 * by @automattic/mini-css-extract-plugin-with-rtl.
 *
 * It will rename the function jsonpScriptSrc generated by that to webpackJsonpScriptSrc
 * and install a new version that checks a user provided variable containing a script
 * version parameter to specify in async chunk URLs.
 *
 * The jsonpScriptSrc override is only for webpack 4 (tested with 4.43 and 4.44).
 *
 * Webpack 5 has official support for this https://github.com/webpack/webpack/pull/8462
 * so it won't be necessary.
 *
 * It will also append the ?ver parameter to CSS chunk hrefs loaded by @automattic/mini-css-extract-plugin-with-rtl.
 */
class AsyncChunkSrcVersionParameterPlugin {
	_applyMainTemplate( mainTemplate ) {
		// Append script version to all async JS chunks loaded with jsonpScriptSrc().
		mainTemplate.hooks.localVars.tap(
			// Use stage 1 to ensure this executes after webpack/lib/web/JsonpMainTemplatePlugin.js.
			{ name: pluginName, stage: 1 },
			( source ) => {
				if ( source.includes( 'function jsonpScriptSrc' ) ) {
					const modSource = source.replace(
						'function jsonpScriptSrc',
						'function webpackJsonpScriptSrc'
					);
					return `${ modSource }

function jsonpScriptSrc(chunkId) {
	var src = webpackJsonpScriptSrc(chunkId);
	if ( window.wcAdminAssets && window.wcAdminAssets.version ) {
		src += '?ver=' + window.wcAdminAssets.version;
	}
	return src;
}
`;
				}

				return source;
			}
		);

		// Append script version to all async CSS chunks loaded by @automattic/mini-css-extract-plugin-with-rtl.
		mainTemplate.hooks.requireEnsure.tap(
			// Use stage 1 to ensure this executes after @automattic/mini-css-extract-plugin-with-rtl.
			{ name: pluginName, stage: 1 },
			( source ) => {
				if (
					source.includes( '// mini-css-extract-plugin CSS loading' )
				) {
					return source.replace(
						'linkTag.href = fullhref;',
						`linkTag.href = fullhref;
if ( window.wcAdminAssets && window.wcAdminAssets.version ) {
	linkTag.href += '?ver=' + window.wcAdminAssets.version;
}`
					);
				}

				return source;
			}
		);
	}

	apply( compiler ) {
		compiler.hooks.thisCompilation.tap( pluginName, ( compilation ) => {
			this._applyMainTemplate( compilation.mainTemplate );
		} );
	}
}

module.exports = AsyncChunkSrcVersionParameterPlugin;
