/**
 * @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' );
const getRepoUrls = require( './get-repo-urls' );

/**
 * Adds various project data to hexo so that it can be accessed in filters.
 *
 * @param {Object} ctx Hexo instance.
 * @param {String} rootPath Project's root path.
 * @param {String} basePath Project's base path.
 * @param {Object} config Project's umberto.json config.
 * @param {String} errorsHtml API errors HTML created by ApiBuilder.
 */
module.exports = ( ctx, {
	rootPath,
	basePath,
	config,
	errorsHtml
} ) => {
	if ( !basePath || !config ) {
		throw new Error( 'Internal: basePath or config not specified.' );
	}

	const projectSlug = config.slug;
	const groups = config.groups || [];
	const groupsModified = groups.map( g => {
		g._url = upath.join( basePath, g.slug, 'index.html' );

		return g;
	} );
	const projectData = {
		// contains groupId of each category and path to this category
		categoryIds: new Map(),
		BASE_PATH: basePath,
		groups: groupsModified,
		errorsHtml,

		// The `_icons` collection contains files that should be copied to the project's assets.
		// They are parsed in the `parseIconTag()` function. See `scripts/filter/after-post-render/parseicontag.js`.
		_icons: new Map()
	};

	// Creates paths to every guide category.
	// Guides categories are defined in umberto.json.
	// Categories can be nested multiple times and that's why this function is needed to build paths to each category.
	function traverseCategories( data, groupId, pathToCategory, groupSlug ) {
		if ( Array.isArray( data.categories ) ) {
			for ( const cat of data.categories ) {
				const newPathToCategory = upath.join( pathToCategory, cat.slug || '' );
				projectData.categoryIds.set( cat.id, {
					category: cat,
					parentCategoryId: data.id,
					groupId,
					groupSlug,
					path: newPathToCategory
				} );
				traverseCategories( cat, groupId, newPathToCategory, groupSlug );
			}
		}
	}

	for ( const g of groups ) {
		const pathToCategory = upath.join( basePath, g.slug );
		projectData.categoryIds.set( g.id, {
			category: null,
			parentCategoryId: null,
			groupId: g.id,
			groupSlug: g.slug,
			path: pathToCategory
		} );

		traverseCategories( g, g.id, pathToCategory, g.slug );
	}

	projectData.config = config;
	// Guides can come from different packages/sub-repos. Repo urls are needed to create 'report issue/contribute' links.
	projectData.guidesToRepos = getRepoUrls( {
		rootPath,
		packages: config.items,
		defaultRepoUrl: config.repoUrlDocs || config.repoUrl
	} );

	if ( !ctx.projectGlobals ) {
		ctx.projectGlobals = {};
	}

	if ( !ctx.projectGlobals[ projectSlug ] ) {
		ctx.projectGlobals[ projectSlug ] = {};
	}

	Object.assign( ctx.projectGlobals[ projectSlug ], projectData );
};
