/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 *
 * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute for Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 *
 * 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
 *
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 *
 * Contributors:
 * Fraunhofer FIRST - Initial API and implementation
 * Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.internal.core.compiler.ast;

import static org.eclipse.objectteams.otdt.core.compiler.IOTConstants.CALLIN_FLAG_DEFINITELY_MISSING_BASECALL;
import static org.eclipse.objectteams.otdt.core.compiler.IOTConstants.CALLIN_FLAG_POTENTIALLY_MISSING_BASECALL;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.SuperReference;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper;

/**
 * NEW for OTDT.
 *
 * A messages send using tsuper has to perform additional checks,
 * because it is legal only if enclosing method and invoked method have
 * the same signature (except for the tsuper-mark argument).
 *
 * What: add appropriate marker argument
 * How:  before actual resolve, resolve the (possibly qualified) tsuper reference
 *       and determine from it the appropriate marker interface.
 *
 * @author stephan
 * @version $Id: TSuperMessageSend.java 23401 2010-02-02 23:56:05Z stephan $
 */
public class TSuperMessageSend extends MessageSend {

	public  TsuperReference tsuperReference;

	/** Check whether this message send contributes to base call analysis */
	@Override
	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
		flowInfo = super.analyseCode(currentScope, flowContext, flowInfo);
		if (this.binding.isCallin())
		{
			MethodBinding tsuperMethod = this.binding;
			if (tsuperMethod.copyInheritanceSrc != null)
				tsuperMethod = tsuperMethod.copyInheritanceSrc;
			if (!MethodModel.hasCallinFlag(tsuperMethod, CALLIN_FLAG_DEFINITELY_MISSING_BASECALL)) { // no contribution if no base call.
				MethodDeclaration callinMethod = (MethodDeclaration)currentScope.methodScope().referenceContext;
				LocalVariableBinding trackingVariable = callinMethod.baseCallTrackingVariable.binding;
				if (MethodModel.hasCallinFlag(tsuperMethod, CALLIN_FLAG_POTENTIALLY_MISSING_BASECALL)) {
					if (   flowInfo.isDefinitelyAssigned(trackingVariable)
						|| flowInfo.isPotentiallyAssigned(trackingVariable))
					{
						currentScope.problemReporter().potentiallyDuplicateBasecall(this);
					} else {
						FlowInfo potential = flowInfo.copy();
						potential.markAsDefinitelyAssigned(trackingVariable);
						flowInfo = FlowInfo.conditional(flowInfo.initsWhenTrue(), potential.initsWhenTrue());
					}
				} else { // tsuper definitely has a base call:
					if (flowInfo.isDefinitelyAssigned(trackingVariable))
						currentScope.problemReporter().definitelyDuplicateBasecall(this);
					else if (flowInfo.isPotentiallyAssigned(trackingVariable))
						currentScope.problemReporter().potentiallyDuplicateBasecall(this);
					if (!flowInfo.isDefinitelyAssigned(trackingVariable))
						flowInfo.markAsDefinitelyAssigned(trackingVariable);
				}
			}
		}
		return flowInfo;
	}

	@Override
	protected TypeBinding findMethodBinding(BlockScope scope) {
		
		// check: is a tsuper call legal in the current context?
		
		AbstractMethodDeclaration context = scope.methodScope().referenceMethod();
		if (context == null 
				|| !CharOperation.equals(this.selector, context.selector)
				|| context.binding.parameters.length != this.argumentTypes.length) 
		{
			scope.problemReporter().tsuperCallsWrongMethod(this);
			return null;
		}

		ReferenceBinding receiverRole;
		if (!(this.actualReceiverType instanceof ReferenceBinding) 
				|| !(receiverRole = (ReferenceBinding)this.actualReceiverType).isSourceRole()) 
		{
			scope.problemReporter().tsuperOutsideRole(context, this, this.actualReceiverType);
			return null;
		}

		ReferenceBinding[] tsuperRoleBindings = receiverRole.roleModel.getTSuperRoleBindings();
	    if (tsuperRoleBindings.length == 0) {
	    	scope.problemReporter().tsuperCallWithoutTsuperRole(receiverRole, this);
	    	return null;
	    }

	    // context is OK, start searching:

	    this.tsuperReference.resolveType(scope);
	    // qualified tsuper? => directly search within the designated tsuper role:
	    if (this.tsuperReference.qualification != null) {
	    	TypeBinding tsuperRole = this.tsuperReference.resolvedType;
	    	if (tsuperRole == null || !tsuperRole.isRole())
	    		return null;
	    	this.binding = scope.getMethod(tsuperRole, this.selector, this.argumentTypes, this);
	    	if (!this.binding.isValidBinding() && ((ProblemMethodBinding)this.binding).declaringClass == null)
	    		this.binding.declaringClass = (ReferenceBinding) tsuperRole;
    		resolvePolyExpressionArguments(this, this.binding, this.argumentTypes, scope);
	    	return this.binding.returnType;
	    }
	    // no qualification => search all tsupers by priority:
	    MethodBinding bestMatch = null;
	    for (int i=tsuperRoleBindings.length-1; i>=0; i--) {
	    	ReferenceBinding tsuperRole = tsuperRoleBindings[i];
	    	MethodBinding candidate = scope.getMethod(tsuperRole, this.selector, this.argumentTypes, this);
	    	if (candidate.isValidBinding()) {
	    		if (scope.parameterCompatibilityLevel(candidate, this.argumentTypes) != Scope.COMPATIBLE) {
	    			scope.problemReporter().tsuperCallsWrongMethod(this);
	    			return candidate.returnType;
	    		}
	    		this.binding = candidate;
	    		resolvePolyExpressionArguments(this, this.binding, this.argumentTypes, scope);
	    		return this.binding.returnType;
	    	}
	    	if (bestMatch == null || 
	    			(bestMatch.problemId() == ProblemReasons.NotFound && candidate.problemId() != ProblemReasons.NotFound))
	    		bestMatch = candidate;
	    }
	    if (bestMatch == null)
	    	bestMatch = new ProblemMethodBinding(this.selector, this.argumentTypes, ProblemReasons.NotFound);
	    if (bestMatch.declaringClass == null)
	    	bestMatch.declaringClass = (ReferenceBinding) this.tsuperReference.resolvedType;
	    this.binding = bestMatch;
	    return this.binding.returnType;
	}
	
	@Override
	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) 
	{
		// for code gen we need to add the marker arg... 
		int len = this.binding.parameters.length;
		TypeBinding[] extendedParameters = new TypeBinding[len+1];
		System.arraycopy(this.binding.parameters, 0, extendedParameters, 0, len);
		char[] tSuperMarkName = TSuperHelper.getTSuperMarkName(this.tsuperReference.resolvedType.enclosingType());
		extendedParameters[len] = currentScope.getType(tSuperMarkName);
	
		// ... and find the copied method binding
		MethodBinding codegenBinding = currentScope.getMethod(this.actualReceiverType, this.selector, extendedParameters, this);
		
		if (codegenBinding.problemId() == ProblemReasons.NotFound) {
			// tsuper.m() may in fact refer to tsuper.super.m().
			// try to find the method as super.tsuper() instead:
			ReferenceBinding superRole = ((ReferenceBinding)this.receiver.resolvedType).superclass();
			codegenBinding = getAlternateMethod(currentScope, superRole, extendedParameters);
			if (codegenBinding == null)
				codegenBinding = getAlternateMethod(currentScope, superRole, this.binding.parameters);
			if (codegenBinding == null)
				throw new InternalCompilerError("cannot find real method binding for tsuper call!"); //$NON-NLS-1$

			this.receiver = new SuperReference(this.receiver.sourceStart, this.receiver.sourceEnd);
			this.receiver.resolvedType = superRole;
			this.receiver.constant = Constant.NotAConstant;
			this.actualReceiverType = superRole;
		}
			
		MethodBinding tsuperMethod = this.binding;
		this.binding = codegenBinding;
		try {
			super.generateCode(currentScope, codeStream, valueRequired);
		} finally {
			this.binding = tsuperMethod;
		}
		
		if (valueRequired && this.binding.isCallin()) {
			if (this.resolvedType != null && this.resolvedType.isValidBinding()) {
				if (this.resolvedType.isBaseType()) {
					// something like: ((Integer)result).intValue()
					char[][] boxtypeName= AstGenerator.boxTypeName((BaseTypeBinding)this.resolvedType);
					codeStream.checkcast(currentScope.getType(boxtypeName, 3));
					codeStream.generateUnboxingConversion(this.resolvedType.id);
				} else {
					// (RefType)result
					codeStream.checkcast(this.resolvedType);
				}
			}
		}
	}

	@SuppressWarnings("hiding")
	@Override
	public void generateArguments(MethodBinding binding, Expression[] arguments, BlockScope currentScope, CodeStream codeStream) 
	{
		super.generateArguments(binding, arguments, currentScope, codeStream);
		// check if we need to pass the marker arg, too:
		TypeBinding[] parameters = this.binding.parameters;
		TypeBinding tsuperMarkerBinding = parameters.length == 0 ? null : parameters[parameters.length-1];
		if (tsuperMarkerBinding == null || !TSuperHelper.isMarkerInterface(tsuperMarkerBinding))
			return;
		codeStream.aconst_null();
		codeStream.checkcast(tsuperMarkerBinding);
	}

	private MethodBinding getAlternateMethod(Scope scope, ReferenceBinding superRole, TypeBinding[] extendedArgumentTypes)
	{
		MethodBinding alternateMethod = scope.getMethod(superRole, this.selector, extendedArgumentTypes, this);
		if (alternateMethod.problemId() == ProblemReasons.NotVisible) {
			return alternateMethod; // want to see this error as IProblem.IndirectTSuperInvisible, cf. ProblemReporter.invalidMethod
		}
		MethodBinding alternateSrc = alternateMethod.copyInheritanceSrc;
		// TODO(SH): binary verbatim copies (no marker arg) are not recognized as copies!
		if (   alternateSrc != null
		    && isRoleOfSuperTeam(alternateSrc.declaringClass, scope))
			return alternateMethod;
		return null;
	}

	@Override
	protected boolean isAnySuperAccess() {
		return true;
	}

	private boolean isRoleOfSuperTeam(ReferenceBinding roleClass, Scope scope) {
		ReferenceBinding site = scope.enclosingSourceType();
		if (!site.isRole())
			return false;
		return site.enclosingType().superclass().isCompatibleWith(roleClass.enclosingType());
	}

	@Override
	public TypeBinding resolveType(BlockScope scope) {
		TypeBinding answer = super.resolveType(scope);
		if (this.binding != null && this.binding.isCallin())
			// restore return type which has been generalized to 'Object':
			return this.resolvedType= MethodModel.getReturnType(this.binding);
	
		return answer;
	}

	@Override
	public StringBuffer printExpression(int indent, StringBuffer output){
		if (this.tsuperReference != null && this.tsuperReference.qualification != null) {
			this.tsuperReference.qualification.printExpression(indent, output);
			output.append("."); //$NON-NLS-1$
		}
	    output.append("tsuper."); //$NON-NLS-1$
	    return super.printExpression(indent, output);
	}

}
