/*******************************************************************************
 * Copyright (c) 2013, 2015 GK Software AG.
 *
 * 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:
 *     Stephan Herrmann - initial API and implementation
 *     Lars Vogel <Lars.Vogel@vogella.com> - Contributions for
 *     						Bug 473178
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;

/**
 * Constraint formula expressing that a given expression must have an exception type.
 * <ul>
 * <li>Expression contains<sub>throws</sub> T</li>
 * </ul>
 */
public class ConstraintExceptionFormula extends ConstraintFormula {

	FunctionalExpression left;

	public ConstraintExceptionFormula(FunctionalExpression left, TypeBinding type) {
		this.left = left;
		this.right = type;
		this.relation = EXCEPTIONS_CONTAINED;
	}

	@Override
	public Object reduce(InferenceContext18 inferenceContext) {
		// JLS 18.2.5
		Scope scope = inferenceContext.scope;
		if (!this.right.isFunctionalInterface(scope))
			return FALSE;
		MethodBinding sam = this.right.getSingleAbstractMethod(scope, true);
		if (sam == null)
			return FALSE;
		if (this.left instanceof LambdaExpression) {
			if (((LambdaExpression)this.left).argumentsTypeElided()) {
				int nParam = sam.parameters.length;
				for (int i = 0; i < nParam; i++)
					if (!sam.parameters[i].isProperType(true))
						return FALSE;
			}
			if (sam.returnType != TypeBinding.VOID && !sam.returnType.isProperType(true))
				return FALSE;
		} else { // reference expression
			if (!((ReferenceExpression)this.left).isExactMethodReference()) {
				int nParam = sam.parameters.length;
				for (int i = 0; i < nParam; i++)
					if (!sam.parameters[i].isProperType(true))
						return FALSE;
				if (sam.returnType != TypeBinding.VOID && !sam.returnType.isProperType(true))
					return FALSE;
			}
		}
		TypeBinding[] thrown = sam.thrownExceptions;
		InferenceVariable[] e = new InferenceVariable[thrown.length];
		int n = 0;
		for (int i = 0; i < thrown.length; i++)
			if (!thrown[i].isProperType(true))
				e[n++] = (InferenceVariable) thrown[i]; // thrown[i] is not a proper type, since it's an exception it must be an inferenceVariable, right?

		/* If throw specification does not encode any type parameters, there are no constraints to be gleaned/gathered from the throw sites.
		   See also that thrown exceptions are not allowed to influence compatibility and overload resolution.
		*/
		if (n == 0)
			return TRUE;

		TypeBinding[] ePrime = null;
		if (this.left instanceof LambdaExpression) {
			LambdaExpression lambda = ((LambdaExpression) this.left).resolveExpressionExpecting(this.right, inferenceContext.scope, inferenceContext);
			if (lambda == null)
				return TRUE; // cannot make use of this buggy constraint
			Set<TypeBinding> ePrimeSet = lambda.getThrownExceptions();
			ePrime = ePrimeSet.toArray(new TypeBinding[ePrimeSet.size()]);
		} else {
			ReferenceExpression referenceExpression = ((ReferenceExpression) this.left).resolveExpressionExpecting(this.right, scope, inferenceContext);
			MethodBinding method = referenceExpression != null ? referenceExpression.binding : null;
			if (method != null)
				ePrime = method.thrownExceptions;
		}
		if (ePrime == null)
			return TRUE;
		int m = ePrime.length;
		List<ConstraintFormula> result = new ArrayList<>();
		actual: for (int i = 0; i < m; i++) {
			if (ePrime[i].isUncheckedException(false))
				continue;
			for (int j = 0; j < thrown.length; j++)
				if (thrown[j].isProperType(true) && ePrime[i].isCompatibleWith(thrown[j]))
					continue actual;
			for (int j = 0; j < n; j++)
				result.add(ConstraintTypeFormula.create(ePrime[i], e[j], SUBTYPE));
		}
		for (int j = 0; j < n; j++)
			inferenceContext.currentBounds.inThrows.add(e[j].prototype());
		return result.toArray(new ConstraintFormula[result.size()]);
	}

	@Override
	Collection<InferenceVariable> inputVariables(final InferenceContext18 context) {
		// from 18.5.2.
		if (this.left instanceof LambdaExpression) {
			if (this.right instanceof InferenceVariable) {
				return Collections.singletonList((InferenceVariable)this.right);
			}
			if (this.right.isFunctionalInterface(context.scope)) {
				LambdaExpression lambda = (LambdaExpression) this.left;
				MethodBinding sam = this.right.getSingleAbstractMethod(context.scope, true); // TODO derive with target type?
				final Set<InferenceVariable> variables = new HashSet<>();
				if (lambda.argumentsTypeElided()) {
					// i)
					int len = sam.parameters.length;
					for (int i = 0; i < len; i++) {
						sam.parameters[i].collectInferenceVariables(variables);
					}
				}
				if (sam.returnType != TypeBinding.VOID) {
					// ii)
					sam.returnType.collectInferenceVariables(variables);
				}
				return variables;
			}
		} else if (this.left instanceof ReferenceExpression) {
			if (this.right instanceof InferenceVariable) {
				return Collections.singletonList((InferenceVariable)this.right);
			}
			if (this.right.isFunctionalInterface(context.scope)) { // TODO: && this.left is inexact
				MethodBinding sam = this.right.getSingleAbstractMethod(context.scope, true); // TODO derive with target type?
				final Set<InferenceVariable> variables = new HashSet<>();
				int len = sam.parameters.length;
				for (int i = 0; i < len; i++) {
					sam.parameters[i].collectInferenceVariables(variables);
				}
				sam.returnType.collectInferenceVariables(variables);
				return variables;
			}
		}
		return EMPTY_VARIABLE_LIST;
	}

	@Override
	public String toString() {
		StringBuffer buf = new StringBuffer().append(LEFT_ANGLE_BRACKET);
		this.left.printExpression(4, buf);
		buf.append(" \u2286throws "); //$NON-NLS-1$
		appendTypeName(buf, this.right);
		buf.append(RIGHT_ANGLE_BRACKET);
		return buf.toString();
	}
}
