/*******************************************************************************
 * Copyright (c) 2004, 2008 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.aspectj.org.eclipse.jdt.core;

import org.aspectj.org.eclipse.jdt.core.compiler.IProblem;

/**
 * Abstract base class for a completion requestor which is passed completion
 * proposals as they are generated in response to a code assist request.
 * <p>
 * This class is intended to be subclassed by clients.
 * </p>
 * <p>
 * The code assist engine normally invokes methods on completion
 * requestor in the following sequence:
 * <pre>
 * requestor.beginReporting();
 * requestor.acceptContext(context);
 * requestor.accept(proposal_1);
 * requestor.accept(proposal_2);
 * ...
 * requestor.endReporting();
 * </pre>
 * If, however, the engine is unable to offer completion proposals
 * for whatever reason, <code>completionFailure</code> is called
 * with a problem object describing why completions were unavailable.
 * In this case, the sequence of calls is:
 * <pre>
 * requestor.beginReporting();
 * requestor.acceptContext(context);
 * requestor.completionFailure(problem);
 * requestor.endReporting();
 * </pre>
 * In either case, the bracketing <code>beginReporting</code>
 * <code>endReporting</code> calls are always made as well as
 * <code>acceptContext</code> call.
 * </p>
 * <p>
 * The class was introduced in 3.0 as a more evolvable replacement
 * for the <code>ICompletionRequestor</code> interface.
 * </p>
 *
 * @see ICodeAssist
 * @since 3.0
 */
public abstract class CompletionRequestor {

	/**
	 * The set of CompletionProposal kinds that this requestor
	 * ignores; <code>0</code> means the set is empty.
	 * 1 << completionProposalKind
	 */
	private int ignoreSet = 0;

	private String[] favoriteReferences;

	/**
	 * The set of CompletionProposal kinds that this requestor
	 * allows for required proposals; <code>0</code> means the set is empty.
	 * 1 << completionProposalKind
	 */
	private int requiredProposalAllowSet[] = null;

	private boolean requireExtendedContext = false;

	/**
	 * Creates a new completion requestor.
	 * The requestor is interested in all kinds of completion
	 * proposals; none will be ignored.
	 *
	 * Calls to this constructor are identical to calls to <code>CompletionRequestor(false)</code>
	 */
	public CompletionRequestor() {
		this(false);
	}

	/**
	 * Creates a new completion requestor.
	 * If <code>ignoreAll</code> is <code>true</code> the requestor is not interested in
	 * all kinds of completion proposals; all will be ignored. For each kind of completion proposals
	 * that is of interest, <code>setIgnored(kind, false)</code> must be called.
	 * If <code>ignoreAll</code> is <code>false</code> the requestor is interested in
	 * all kinds of completion proposals; none will be ignored.
	 *
	 * @param ignoreAll <code>true</code> to ignore all kinds of completion proposals,
	 * and <code>false</code> to propose all kinds
	 *
	 * @since 3.4
	 */
	public CompletionRequestor(boolean ignoreAll) {
		this.ignoreSet = ignoreAll ? 0xffffffff : 0x00000000;
	}

	/**
	 * Returns whether the given kind of completion proposal is ignored.
	 *
	 * @param completionProposalKind one of the kind constants declared
	 * on <code>CompletionProposal</code>
	 * @return <code>true</code> if the given kind of completion proposal
	 * is ignored by this requestor, and <code>false</code> if it is of
	 * interest
	 * @see #setIgnored(int, boolean)
	 * @see CompletionProposal#getKind()
	 */
	public boolean isIgnored(int completionProposalKind) {
		if (completionProposalKind < CompletionProposal.FIRST_KIND
			|| completionProposalKind > CompletionProposal.LAST_KIND) {
				throw new IllegalArgumentException("Unknown kind of completion proposal: "+completionProposalKind); //$NON-NLS-1$
		}
		return 0 != (this.ignoreSet & (1 << completionProposalKind));
	}

	/**
	 * Sets whether the given kind of completion proposal is ignored.
	 *
	 * @param completionProposalKind one of the kind constants declared
	 * on <code>CompletionProposal</code>
	 * @param ignore <code>true</code> if the given kind of completion proposal
	 * is ignored by this requestor, and <code>false</code> if it is of
	 * interest
	 * @see #isIgnored(int)
	 * @see CompletionProposal#getKind()
	 */
	public void setIgnored(int completionProposalKind, boolean ignore) {
		if (completionProposalKind < CompletionProposal.FIRST_KIND
			|| completionProposalKind > CompletionProposal.LAST_KIND) {
				throw new IllegalArgumentException("Unknown kind of completion proposal: "+completionProposalKind); //$NON-NLS-1$
		}
		if (ignore) {
			this.ignoreSet |= (1 << completionProposalKind);
		} else {
			this.ignoreSet &= ~(1 << completionProposalKind);
		}
	}

	/**
	 * Returns whether a proposal of a given kind with a required proposal
	 * of the given kind is allowed.
	 *
	 * @param proposalKind one of the kind constants declared
	 * @param requiredProposalKind one of the kind constants declared
	 * on <code>CompletionProposal</code>
	 * @return <code>true</code> if a proposal of a given kind with a required proposal
	 * of the given kind is allowed by this requestor, and <code>false</code>
	 * if it isn't of interest.
	 * <p>
	 * By default, all kinds of required proposals aren't allowed.
	 * </p>
	 * @see #setAllowsRequiredProposals(int, int, boolean)
	 * @see CompletionProposal#getKind()
	 * @see CompletionProposal#getRequiredProposals()
	 *
	 * @since 3.3
	 */
	public boolean isAllowingRequiredProposals(int proposalKind, int requiredProposalKind) {
		if (proposalKind < CompletionProposal.FIRST_KIND
			|| proposalKind > CompletionProposal.LAST_KIND) {
				throw new IllegalArgumentException("Unknown kind of completion proposal: "+requiredProposalKind); //$NON-NLS-1$
			}

		if (requiredProposalKind < CompletionProposal.FIRST_KIND
			|| requiredProposalKind > CompletionProposal.LAST_KIND) {
				throw new IllegalArgumentException("Unknown required kind of completion proposal: "+requiredProposalKind); //$NON-NLS-1$
		}
		if (this.requiredProposalAllowSet == null) return false;

		return 0 != (this.requiredProposalAllowSet[proposalKind] & (1 << requiredProposalKind));
	}

	/**
	 * Sets whether a proposal of a given kind with a required proposal
	 * of the given kind is allowed.
	 *
	 * A required proposal of a given kind is proposed even if {@link #isIgnored(int)}
	 * return <code>true</code> for that kind.
	 *
	 * Currently only a subset of kinds support required proposals. To see what combinations
	 * are supported you must look at {@link CompletionProposal#getRequiredProposals()}
	 * documentation.
	 *
	 * @param proposalKind one of the kind constants declared
	 * @param requiredProposalKind one of the kind constants declared
	 * on <code>CompletionProposal</code>
	 * @param allow <code>true</code> if a proposal of a given kind with a required proposal
	 * of the given kind is allowed by this requestor, and <code>false</code>
	 * if it isn't of interest
	 * @see #isAllowingRequiredProposals(int, int)
	 * @see CompletionProposal#getKind()
	 * @see CompletionProposal#getRequiredProposals()
	 *
	 * @since 3.3
	 */
	public void setAllowsRequiredProposals(int proposalKind, int requiredProposalKind, boolean allow) {
		if (proposalKind < CompletionProposal.FIRST_KIND
			|| proposalKind > CompletionProposal.LAST_KIND) {
				throw new IllegalArgumentException("Unknown kind of completion proposal: "+requiredProposalKind); //$NON-NLS-1$
		}
		if (requiredProposalKind < CompletionProposal.FIRST_KIND
			|| requiredProposalKind > CompletionProposal.LAST_KIND) {
				throw new IllegalArgumentException("Unknown required kind of completion proposal: "+requiredProposalKind); //$NON-NLS-1$
		}

		if (this.requiredProposalAllowSet == null) {
			this.requiredProposalAllowSet = new int[CompletionProposal.LAST_KIND + 1];
		}

		if (allow) {
			this.requiredProposalAllowSet[proposalKind] |= (1 << requiredProposalKind);
		} else {
			this.requiredProposalAllowSet[proposalKind] &= ~(1 << requiredProposalKind);
		}
	}

	/**
	 * Returns the favorite references which are used to compute some completion proposals.
	 * <p>
	 * A favorite reference is a qualified reference as it can be seen in an import statement.<br>
	 * e.g. <code>{"java.util.Arrays"}</code><br>
	 * It can be an on demand reference.<br>
	 * e.g. <code>{"java.util.Arrays.*"}</code>
	 * It can be a reference to a static method or field (as in a static import)<br>
	 * e.g. <code>{"java.util.Arrays.equals"}</code>
	 * </p>
	 * <p>
	 * Currently only on demand type references (<code>"java.util.Arrays.*"</code>),
	 * references to a static method or a static field are used to compute completion proposals.
	 * Other kind of reference could be used in the future.
	 * </p>
	 * @return favorite imports
	 *
	 * @since 3.3
	 */
	public String[] getFavoriteReferences() {
		return this.favoriteReferences;
	}

	/**
	 * Set the favorite references which will be used to compute some completion proposals.
	 * A favorite reference is a qualified reference as it can be seen in an import statement.<br>
	 *
	 * @param favoriteImports
	 *
	 * @see #getFavoriteReferences()
	 *
	 * @since 3.3
	 */
	public void setFavoriteReferences(String[] favoriteImports) {
		this.favoriteReferences = favoriteImports;
	}

	/**
	 * Pro forma notification sent before reporting a batch of
	 * completion proposals.
	 * <p>
	 * The default implementation of this method does nothing.
	 * Clients may override.
	 * </p>
	 */
	public void beginReporting() {
		// do nothing
	}

	/**
	 * Pro forma notification sent after reporting a batch of
	 * completion proposals.
	 * <p>
	 * The default implementation of this method does nothing.
	 * Clients may override.
	 * </p>
	 */
	public void endReporting() {
		// do nothing
	}

	/**
	 * Notification of failure to produce any completions.
	 * The problem object explains what prevented completing.
	 * <p>
	 * The default implementation of this method does nothing.
	 * Clients may override to receive this kind of notice.
	 * </p>
	 *
	 * @param problem the problem object
	 */
	public void completionFailure(IProblem problem) {
		// default behavior is to ignore
	}

	/**
	 * Proposes a completion. Has no effect if the kind of proposal
	 * is being ignored by this requestor. Callers should consider
	 * checking {@link #isIgnored(int)} before avoid creating proposal
	 * objects that would only be ignored.
	 * <p>
	 * Similarly, implementers should check
	 * {@link #isIgnored(int) isIgnored(proposal.getKind())}
	 * and ignore proposals that have been declared as uninteresting.
	 * The proposal object passed is only valid for the duration of
	 * completion operation.
	 *
	 * @param proposal the completion proposal
	 * @exception IllegalArgumentException if the proposal is null
	 */
	public abstract void accept(CompletionProposal proposal);

	/**
	 * Propose the context in which the completion occurs.
	 * <p>
	 * This method is called one and only one time before any call to
	 * {@link #accept(CompletionProposal)}.
	 * The default implementation of this method does nothing.
	 * Clients may override.
	 * </p>
	 * @param context the completion context
	 *
	 * @since 3.1
	 */
	public void acceptContext(CompletionContext context) {
		// do nothing
	}

	/**
	 * Returns whether this requestor requires an extended context.
	 *
	 * By default this method return <code>false</code>.
	 *
	 * @return <code>true</code> if this requestor requires an extended context.
	 *
	 * @see CompletionContext#isExtended()
	 *
	 * @since 3.4
	 */
	public boolean isExtendedContextRequired() {
		return this.requireExtendedContext;
	}


	/**
	 * Sets whether this requestor requires an extended context.
	 *
	 * @param require <code>true</code> if this requestor requires an extended context.
	 *
	 * @see CompletionContext#isExtended()
	 *
	 * @since 3.4
	 */
	public void setRequireExtendedContext(boolean require) {
		this.requireExtendedContext = require;
	}

	/**
	 * If this returns true, exclude test sources and dependencies.
	 * 
	 * @return <code>true</code> if this requestor does not want to get any completions from test code.
	 * @see IClasspathAttribute#TEST
	 * @since 3.14
	 */
	public boolean isTestCodeExcluded() {
		return false;
	}
}
