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

'use strict';

const AbstractParser = require( './abstractparser' );
const ReflectionKind = require( './reflectionkind' );

module.exports = class TypeParser extends AbstractParser {
	/**
	 * @param {BaseReflection} item
	 * @returns {Boolean}
	 */
	canParse( item ) {
		return item.kind === ReflectionKind.TypeAlias;
	}

	/**
	 * @param {LiteralObjectReflection} item
	 * @param {String} parentName
	 * @returns {Object}
	 */
	parse( item, parentName ) {
		const result = {
			id: item.id,
			name: item.name,
			memberof: parentName,
			longname: this.getLongName( item, parentName ),

			scope: 'inner',
			kind: this.getKind( item ),
			extraId: this.getExtraId( item ),
			file: this.getFile( item ),
			skipSource: this.shouldSkipSource( item ),
			description: this.getComment( item ),
			deprecated: this.isDeprecated( item ),
			firedBy: this.getFiredBy( item, parentName ),

			// This property will be filled in the post-processing phase.
			typeParameters: null
		};

		// There are various distinct type definitions that are rendered in own way by Umberto:
		// 1. a function type - show params and return type.
		// 2. an object type - show all its properties.
		// 3. a type alias - show the type name.
		const isFunctionType = item.type?.declaration?.signatures;

		if ( isFunctionType ) {
			// Needed for post-processing once all project reflections are converted.
			result._signature = item.type.declaration.signatures[ 0 ];

			result.description = this.getComment( result._signature );
			result.type = {
				names: [
					'function'
				]
			};

			// These properties will be filled in the post-processing phase.
			result.returns = null;
			result.params = null;
		} else {
			// Needed for post-processing once all project reflections are converted.
			result._signature = item;

			// These properties will be filled in the post-processing phase.
			result.properties = null;
			result.type = null;
		}

		return result;
	}
};
