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

'use strict';

const upath = require( 'upath' );

/**
 * Changes page path to reflect configuration from umberto.json.
 * page.path property defines the location of a file out by hexo.
 * It's used in this filter to set urls of generated pages (their location in build directory).
 * Also applies a slug if needed.
 * This is the third filter run for each documentation page (except API docs).
 */
hexo.extend.filter.register( 'before_post_render', page => {
	if ( !hexo.projectGlobals || !hexo.projectGlobals[ page.projectName ] ) {
		return;
	}
	const existsHexoWatcher = hexo.source && hexo.source.watcher !== null;
	const projectCategories = hexo.projectGlobals[ page.projectName ].categoryIds;
	const category = projectCategories.get( page.category );
	// jscs:disable
	const fullSourcePath = page.full_source;
	// jscs:enable
	const basePath = hexo.projectGlobals[ page.projectName ].BASE_PATH;
	// Cache original page path.
	page.oldDataPath = page.path;

	if ( !category ) {
		return;
	}

	const categoryPath = category.path;
	const basename = upath.basename( page.path );

	if ( page.url ) {
		// Allow setting custom page url via front matter.
		page.path = upath.join( basePath, `${ page.url }.html` );
	} else if ( typeof page.slug === 'string' && page.slug !== '' ) {
		// Allow setting custom file name if it's supposed to be different than original file name.
		page.path = upath.join(
			categoryPath,
			basename.replace( basename.substring( 0, basename.lastIndexOf( '.' ) ), page.slug )
		);
	} else {
		// Default filename and path.
		page.path = upath.join( categoryPath, basename );
	}

	if ( !hexo.projectGlobals[ page.projectName ].pagePaths ) {
		hexo.projectGlobals[ page.projectName ].pagePaths = [];
	}

	// If the path was already used, means we have two guides with same name and same category, which is an error.
	const existingPath = hexo.projectGlobals[ page.projectName ].pagePaths.find( p => p.newDataPath === page.path );

	// Get guide paths to show with an error.
	// Do not throw error when files are watched.
	if ( !existsHexoWatcher && existingPath ) {
		const firstPath = extractPath( existingPath.fullSourcePath );
		const secondPath = extractPath( fullSourcePath );

		throw new Error( `Document: ${ firstPath } is in conflict with: ${ secondPath }` );
	}

	// Store path to the page.
	hexo.projectGlobals[ page.projectName ].pagePaths.push( {
		newDataPath: page.path,
		oldDataPath: page.oldDataPath,
		fullSourcePath
	} );

	function extractPath( str ) {
		if ( typeof str !== 'string' ) {
			return;
		}

		// jscs:disable
		return str.replace( upath.join( hexo.source_dir, basePath ), '' );
		// jscs:enable
	}

	return page;
}, 6 );
