/**
 * @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md.
 */

'use strict';

const crypto = require( 'crypto' );
const upath = require( 'upath' );
const logCrossProjectReference = require( './logcrossprojectreference' );

const ICON_REGEXP = /\\?{@icon(?:\s+@(\w+))?\s+([^}\s]+)\s*([^}]*)\\?}/g;

/**
 * Replaces the `{@icon [@projectName] path/to/icon}` expression with the HTML snippet:
 *
 *      <img src="../path/to/icon" class="editor-icon" />
 *
 * @param {Object} page
 * @param {Object} hexo
 * @returns {Object}
 */
module.exports = function parseIconTag( page, hexo ) {
	const relativeUrlHelper = hexo.extend.helper.store.relative_url;

	page.content = page.content.replace( ICON_REGEXP, ( match, iconProject, iconPath, alternativeText ) => {
		// Cross project references are not supported.
		if ( iconProject ) {
			return logCrossProjectReference( { expression: match, source: page.source } );
		}

		if ( match.startsWith( '\\{' ) ) {
			return match.replace( /^\\{/, '{' ).replace( /\\}$/, '}' );
		}

		const projectDetails = hexo.projectGlobals[ page.projectName ];
		const fileName = sha1( iconPath ).substr( 0, 10 ) + upath.extname( iconPath );

		// Map the original file name with the hashed version to predict the path when copying assets.
		projectDetails._icons.set( iconPath, fileName );

		let alt = '';

		if ( alternativeText ) {
			alt = `alt="${ alternativeText }" `;
		}

		const absoluteLikePath = upath.join( page.projectName, projectDetails.config.version, 'assets', 'icons', fileName );

		return [
			'<span class="editor-icon">' +
				`<img src="${ relativeUrlHelper( page.path, absoluteLikePath ) }" loading="lazy" class="editor-icon__image" ${ alt }/>` +
			'</span>'
		].join( '' );
	} );

	return page;
};

/**
 * @param {String} value
 * @return {String}
 */
function sha1( value ) {
	const shasum = crypto.createHash( 'sha1' );
	shasum.update( value );

	return shasum.digest( 'hex' );
}
