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

'use strict';

const escapeLongname = require( '../../helpers/escape-longname' );

/**
 * Handles filenames of various entities. Makes sure filenames are unique and do not contain forbidden characters.
 * Allows to get a filename for a doclet's longname.
 */
module.exports = class FileNameManager {
	constructor() {
		this.longnameToUrl = new Map();
		this.fileNames = new Set();
	}

	/**
	 * Registers file url associated with given longname and returns it.
	 *
	 * @param {String} longname Longname of an entity, longname is entity's identifier.
	 * @returns {String} fileUrl
	 */
	registerFilename( longname ) {
		let fileUrl;

		if ( this.longnameToUrl.has( longname ) ) {
			fileUrl = this.longnameToUrl.get( longname );
		} else {
			fileUrl = this._createUniqueFilename( escapeLongname( longname ) + '.html' );
			this._registerUrl( longname, fileUrl );
		}

		return fileUrl;
	}

	/**
	 * Gets file name associated with given longname.
	 * @param {String} longname
	 * @returns {String|null}
	 */
	getFilename( longname ) {
		return this.longnameToUrl.has( longname ) ? this.longnameToUrl.get( longname ) : null;
	}

	/**
	 * Gets url. For example as href string for links.
	 * @param longname
	 * @param hash Hash fragment to link using an id.
	 * @returns {String|null}
	 */
	getUrl( longname, hash = '' ) {
		const fileUrl = this.longnameToUrl.get( longname );

		hash = hash ? `#${ hash }` : '';

		if ( fileUrl ) {
			return encodeURI( fileUrl + hash );
		} else {
			return null;
		}
	}

	/**
	 * @private
	 */
	_registerUrl( longname, url ) {
		this.longnameToUrl.set( longname, url );
	}

	_createUniqueFilename( str ) {
		let filename = str;
		let counter = 1;

		while ( this.fileNames.has( filename ) ) {
			filename = `${ str }_${ counter++ }`;
		}

		this.fileNames.add( filename );

		return filename;
	}
};
