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

	/**
	 * Checks if the accessor is readonly.
	 *
	 * @override
	 * @param {AccessorReflection} item
	 * @returns {Boolean}
	 */
	isReadonly( item ) {
		return !item.setSignature;
	}

	/**
	 * @param {AccessorReflection} item
	 * @param {String} parentName
	 * @returns {Object}
	 */
	parse( item, parentName ) {
		// A getter and setter can't be overloaded, so their first signature (if exists) is the only one.
		// Starting from `typedoc@0.23`, these properties are no longer an array.
		const { getSignature, setSignature } = item;

		return {
			// Needed for post-processing once all project reflections are converted.
			_signature: [ getSignature || {}, setSignature || {} ],

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

			scope: this.getScope( item ),
			readonly: this.isReadonly( item ),
			access: this.getVisibilityIncludingSignature( item ),
			kind: this.getKind( item ),
			extraId: this.getExtraId( item ),
			description: this.getComment( getSignature || setSignature ),
			file: this.getFile( item ),
			skipSource: this.shouldSkipSource( getSignature || setSignature ),
			deprecated: this.isDeprecated( getSignature || setSignature ),
			inherited: !!item.inheritedFrom,

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

	/**
	 * Returns the access type for the item based on its signatures.
	 *
	 * @param {AccessorReflection} item
	 * @returns {'public'|'internal'|'protected'|'private'}
	 */
	getVisibilityIncludingSignature( item ) {
		if ( item.setSignature ) {
			return this.getVisibility( item.setSignature );
		}

		if ( item.getSignature ) {
			return this.getVisibility( item.getSignature );
		}
		return this.getVisibility( item );
	}
};
