/**
 * @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 MethodParser extends AbstractParser {
	/**
	 * @param {BaseReflection} item
	 * @returns {Boolean}
	 */
	canParse( item ) {
		return item.kind === ReflectionKind.Method;
	}

	/**
	 * @param {MethodReflection|ConstructorReflection} item
	 * @param {String} parentName
	 * @returns {Array.<Object>}
	 */
	parse( item, parentName ) {
		return item.signatures.map( ( signature, index ) => {
			const doclet = {
				// Needed for post-processing once all project reflections are converted.
				_signature: signature,

				id: item.id,
				name: item.name,
				memberof: parentName,
				longname: this.getLongName( item, parentName ),

				scope: this.getScope( item ),
				kind: this.getKind( item ),
				access: this.getVisibilityIncludingSignature( item, index ),
				extraId: this.getExtraId( item ),
				fires: this.getFiredEvents( signature, parentName ),
				description: this.getComment( signature ),
				file: this.getFile( item, index ),
				skipSource: this.shouldSkipSource( signature ),
				deprecated: this.isDeprecated( signature ),
				inherited: !!signature.inheritedFrom,
				see: this.getRelated( signature, parentName ),

				isOverloaded: item.signatures.length > 1,
				label: this._getLabelName( signature ),

				// These properties will be filled in the post-processing phase.
				returns: null,
				params: null,
				typeParameters: null
			};

			// Add a label as suffix for overloaded members.
			if ( doclet.label ) {
				doclet.extraId += ':' + doclet.label;
			}

			return doclet;
		} );
	}

	/**
	 * Returns the access type for the item based on its signatures.
	 *
	 * @param {MethodReflection|ConstructorReflection} item
	 * @param {Number} sourceIndex
	 * @returns {'public'|'internal'|'protected'|'private'}
	 */
	getVisibilityIncludingSignature( item, sourceIndex ) {
		const signatureVisibility = this.getVisibility( item.signatures[ sourceIndex ] );

		if ( signatureVisibility !== 'public' ) {
			return signatureVisibility;
		}

		return this.getVisibility( item );
	}
};
