/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 *
 * Copyright 2003, 2006 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute for Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * $Id: CalloutMappingDeclaration.java 23401 2010-02-02 23:56:05Z stephan $
 *
 * 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 org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator;

import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameBINDOUT;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCALLOUT_OVERRIDE;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameget;


/**
 * NEW for OTDT.
 *
 * Main responsibility: type checking
 *
 * @author Markus Witte
 * @version $Id: CalloutMappingDeclaration.java 23401 2010-02-02 23:56:05Z stephan $
 */
public class CalloutMappingDeclaration extends AbstractMethodMappingDeclaration
{
	public int calloutKind;
	public int declaredModifiers = 0;
	public int modifiersSourceStart; // start of declared modifiers (visibility)
	public MethodSpec baseMethodSpec;


	// might want to make this configurable via compiler options, but
	// note that currently this flag affects only bindings with signatures!
	private static final boolean ALLOW_DECAPSULATION = true;

	public CalloutMappingDeclaration(CompilationResult compilationResult)
	{
		super(compilationResult);
	}

	public void setCalloutKind(boolean isOverride) {
		this.calloutKind = isOverride ?
								TokenNameCALLOUT_OVERRIDE :
								TokenNameBINDOUT;

	}


	/** add a base method spec, iff none has been given yet. */
	@Override
	public void checkAddBasemethodSpec(MethodSpec baseSpec) {
		if (this.baseMethodSpec == null)
			this.baseMethodSpec = baseSpec;
	}

	/**
	 * Check all parameters in methodSpec against the resolved role method.
	 * Also record which parameters (including result) need translation (lifting/lowering).
	 *
	 * Pre: not called if parameter mappings are present.
     *
	 * @param methodSpec maybe null, signaling we are just inferring an implicit callout.
	 * @param roleParams
	 * @param baseParams
	 */
	public boolean internalCheckParametersCompatibility(
			MethodSpec methodSpec,
			TypeBinding[] roleParams,
			TypeBinding[] baseParams)
	{
		if (roleParams.length < baseParams.length) {
			if (methodSpec != null) {// don't report in infer-mode
				this.scope.problemReporter().tooFewArgumentsInMethodMapping(this.roleMethodSpec, methodSpec, true/*callout*/);
				this.binding.tagBits |= TagBits.HasMappingIncompatibility;
			}
			return false;
		} else {
			for (int j = 0; j < baseParams.length; j++) {
				Config oldConfig = Config.createOrResetConfig(this);
				try {
					TypeBinding roleParam = roleParams[j];
					TypeBinding roleParamLeaf = roleParam.leafComponentType();
					TypeBinding roleBaseLeaf = null;
					if (   roleParamLeaf instanceof ReferenceBinding
						&& ((ReferenceBinding)roleParamLeaf).isRole())
					{
						roleParam = TeamModel.strengthenRoleType(
								this.scope.enclosingSourceType(), roleParam);
						roleBaseLeaf = ((ReferenceBinding)roleParam.leafComponentType()).baseclass();
					}
					TypeBinding baseParam = baseParams[j];
					if (!roleParam.isCompatibleWith(baseParam)) {
						if (!RoleTypeCreator.isCompatibleViaBaseAnchor(this.scope, baseParam, roleParam, TokenNameBINDOUT))
						{
							// try auto(un)boxing:
							if (this.scope.isBoxingCompatibleWith(roleParam, baseParam))
								continue; // success through (un)boxing

							if (methodSpec == null)
								return false; // when inferring one error suffices to abort.

							if (methodSpec.hasSignature && roleBaseLeaf != null)
								this.scope.problemReporter().typeMismatchErrorPotentialLower(
										methodSpec.arguments[j], roleParam, baseParam, roleBaseLeaf);
							else
								this.scope.problemReporter().incompatibleMappedArgument(
										roleParam, baseParam, methodSpec, j, /*callout*/true);
							this.binding.tagBits |= TagBits.HasMappingIncompatibility;
						}
					} else {
						this.roleMethodSpec.argNeedsTranslation[j] = Config.getLoweringRequired();
					}
				} finally {
					Config.removeOrRestore(oldConfig, this);
				}
			}
		}
		return true;
	}


	public void checkReturnCompatibility(MethodSpec methodSpec)
	{
		TypeBinding roleReturn = this.roleMethodSpec.resolvedType();
		TypeBinding baseReturn = methodSpec.resolvedType();
		if (roleReturn != null) {
			if (baseReturn == null) {
				this.scope.problemReporter().returnRequiredInMethodMapping(
						methodSpec, roleReturn, true/*callout*/);
			} else {
				// build a receiver (_OT$base):
				AstGenerator gen = new AstGenerator(methodSpec.sourceStart, methodSpec.sourceEnd);
				SingleNameReference baseRef = gen.singleNameReference(IOTConstants._OT_BASE);
				baseRef.binding = RoleTypeCreator.findResolvedVariable(this.scope.classScope(), IOTConstants._OT_BASE);
				// maybe wrap return type relative to _OT$base
				baseReturn = RoleTypeCreator.maybeWrapQualifiedRoleType(
						this.scope,
						baseRef,
						baseReturn,
						methodSpec.returnType);
				if (this.roleMethodSpec.returnType == null)
					this.roleMethodSpec.returnType = gen.typeReference(roleReturn);
				if (   roleReturn == TypeBinding.VOID
				    || baseReturn.isCompatibleWith(roleReturn))
				{
					this.roleMethodSpec.returnType.resolvedType = roleReturn;
				} else {
					TypeBinding roleToLiftTo = TeamModel.getRoleToLiftTo(this.scope, baseReturn, roleReturn, false, methodSpec);
					if (roleToLiftTo != null)
					{
						// success by translation
						this.roleMethodSpec.returnNeedsTranslation = true;
						this.roleMethodSpec.returnType.resolvedType = roleToLiftTo; // instantiated.
						return; // if successful we're done.
					}
					// try auto(un)boxing:
					if (this.scope.isBoxingCompatibleWith(baseReturn, roleReturn)) {
						this.roleMethodSpec.returnType.resolvedType = roleReturn;
						return; // success by (un)boxing
					}

					this.scope.problemReporter().calloutIncompatibleReturnType(
							this.roleMethodSpec, methodSpec);
					this.binding.tagBits |= TagBits.HasMappingIncompatibility;
				}
			}
		}
	}


	/**
	 * Only one check needs to be performed for callout-to-field:
	 * @param fieldSpec
	 */
	protected void checkTypeCompatibility(FieldAccessSpec fieldSpec)
	{
		// make sure roleMethodSpec has a returnType, because that is going to be updated below:
		if (this.roleMethodSpec.returnType == null) {
			AstGenerator gen = new AstGenerator(this.roleMethodSpec.sourceStart, this.roleMethodSpec.sourceEnd);
			this.roleMethodSpec.returnType = gen.typeReference(this.roleMethodSpec.resolvedType());
		}

		TypeBinding requiredType = null;
		TypeBinding providedType = null;

		if (fieldSpec.calloutModifier == TokenNameget) {
			requiredType = this.roleMethodSpec.resolvedType();
			providedType = fieldSpec.resolvedType();
			if (providedType.isCompatibleWith(requiredType)) {
				if (this.roleMethodSpec.returnType.resolvedType == null)
                    this.roleMethodSpec.returnType.resolvedType = requiredType; // need a valid type here
				return; // OK => done
			} else {
				TypeBinding roleToLiftTo = TeamModel.getRoleToLiftTo(this.scope, providedType, requiredType, false, fieldSpec);
				if (roleToLiftTo != null)
				{
					// success by translation
					this.roleMethodSpec.returnNeedsTranslation = true;
					this.roleMethodSpec.returnType.resolvedType = roleToLiftTo; // instantiated.
					return; // OK => done.
				}
				if (requiredType == TypeBinding.VOID) {
					this.scope.problemReporter().fieldAccessHasNoEffect(this.roleMethodSpec, fieldSpec);
					this.roleMethodSpec.returnType.resolvedType = requiredType; // keep going..
					return; // warned
				}
			}
		} else { // 'set'
			if (this.roleMethodSpec.resolvedMethod.returnType != TypeBinding.VOID) {
				this.scope.problemReporter().calloutSetCantReturn(this.roleMethodSpec);
				this.binding.tagBits |= TagBits.HasMappingIncompatibility;
			}
			this.roleMethodSpec.returnType.resolvedType = TypeBinding.VOID;
			TypeBinding[] params = this.roleMethodSpec.resolvedMethod.parameters;
			if (params == null || params.length == 0) {
				this.scope.problemReporter().calloutToFieldMissingParameter(this.roleMethodSpec, fieldSpec);
				this.binding.tagBits |= TagBits.HasMappingIncompatibility;
				return; // don't report more problems
			}
			providedType = params[0];
			requiredType = fieldSpec.resolvedType();
			if (providedType.isCompatibleWith(requiredType))
				return;
		}
		// fall through in any case of incompatibility:
		this.scope.problemReporter().calloutIncompatibleFieldType(
				this.roleMethodSpec, fieldSpec, requiredType, providedType);
		this.binding.tagBits |= TagBits.HasMappingIncompatibility;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.compiler.ast.AbstractMethodMappingDeclaration#checkModifiers(org.eclipse.jdt.internal.compiler.lookup.CallinCalloutScope)
	 */
	@Override
	protected void checkModifiers(boolean haveBaseMethods, ReferenceBinding baseType) {
		boolean roleHasImplementation = false;
		MethodBinding roleMethod = this.roleMethodSpec.resolvedMethod;
		if (!roleMethod.isValidBinding())
			return;
		// update modifiers after tsuper has generated callout methods (perhaps giving implementation to abstract decl)
		if (roleMethod.isAbstract() && roleMethod.copyInheritanceSrc != null && !roleMethod.copyInheritanceSrc.isAbstract())
			roleMethod.modifiers &= ~ClassFileConstants.AccAbstract;
		roleHasImplementation = !roleMethod.isAbstract();

		if (roleHasImplementation != isCalloutOverride())
		{
			if (roleHasImplementation)
			{
				if (isCalloutMethod(roleMethod)) {
					if (   roleMethod.declaringClass != this.scope.enclosingSourceType()
						|| roleMethod.copyInheritanceSrc != null)  // "local" callouts (not copied) are treated in
					{											   // MethodMappingResolver.checkForDuplicateMethodMappings()
						this.scope.problemReporter().regularCalloutOverridesCallout(this, roleMethod);
					}
				} else {
					this.scope.problemReporter().regularCalloutOverrides(this);
				}
			}
			else // isCalloutOverride() but not really overriding
			{
				this.scope.problemReporter().abstractMethodBoundAsOverrideCallout(this);
				AbstractMethodDeclaration roleMethodDeclaration = roleMethod.sourceMethod();
				if(roleMethodDeclaration != null)
				{
					roleMethodDeclaration.ignoreFurtherInvestigation = true;
					this.ignoreFurtherInvestigation = true;
				}

			}
		}
		if (roleMethod.isCallin()) {
			this.scope.problemReporter().calloutBindingCallin(this.roleMethodSpec);
		}
		if (hasErrors()) {
			// unsuccessful attempt to implement role method as callout,
			// mark the method as erroneous:
			if (this.roleMethodSpec.resolvedMethod != null && this.roleMethodSpec.resolvedMethod.isAbstract())
			{
				AbstractMethodDeclaration methodDecl = this.roleMethodSpec.resolvedMethod.sourceMethod();
				if (methodDecl != null)
					methodDecl.tagAsHavingErrors(); // prevent abstract-error
			}
		}
	}
	private boolean isCalloutMethod(MethodBinding method) {
		if (method.copyInheritanceSrc != null)
			method = method.copyInheritanceSrc;
		if (method.declaringClass.isBinaryBinding()) {
			// fault in types adds callinCallouts for binary types (late attribute)
			Dependencies.ensureBindingState(method.declaringClass, ITranslationStates.STATE_FAULT_IN_TYPES);
		}
		CallinCalloutBinding[] bindings = method.declaringClass.callinCallouts;
		if (bindings != null)
		{
			for (int i = 0; i < bindings.length; i++) {
				if (bindings[i]._roleMethodBinding == method)
					return true;
			}
		}
		return false;
	}

	protected void checkThrownExceptions(MethodSpec baseSpec) {
		if (   this.hasSignature
			&& !this.roleMethodSpec.resolvedMethod.isValidBinding()
			&& this.roleMethodSpec.problemId() == ProblemReasons.NotFound)
			return; // not checking for shorthand declarations

		checkThrownExceptions(baseSpec.resolvedMethod, this.roleMethodSpec.resolvedMethod);
	}

	public StringBuffer print(int indent, StringBuffer output)
	{
		printIndent(indent,output);
		if (this.declaredModifiers != 0)
			printModifiers(this.declaredModifiers, output);
		printShort(0,output);
		if(this.mappings!=null)
		{
			output.append(" with {\n"); //$NON-NLS-1$
			int length = this.mappings.length;
			for(int t=0;t<length;t++)
			{
				printIndent(indent+1,output);
                this.mappings[t].print(0,output);
				if(t<length-1)
					output.append(",\n"); //$NON-NLS-1$
				else
					output.append("\n"); //$NON-NLS-1$
			}
			printIndent(indent, output);
			output.append("}"); //$NON-NLS-1$
		} else {
			output.append(";"); //$NON-NLS-1$
		}

		return output;
	}

    public StringBuffer printShort(int indent, StringBuffer output)
    {
    	printIndent(indent,output);
        this.roleMethodSpec.print(0,output);
        if(this.calloutKind==TokenNameCALLOUT_OVERRIDE)
            output.append(" => "); //$NON-NLS-1$
        else
            output.append(" -> "); //$NON-NLS-1$

        if (this.baseMethodSpec != null)
        	this.baseMethodSpec.print(0,output);
        else
        	output.append(" <nullBaseMethod>"); //$NON-NLS-1$
        return output;
    }

	public void traverse(ASTVisitor visitor, ClassScope classScope)
	{
		if(visitor.visit(this, classScope))
		{
			if (this.roleMethodSpec != null)
				this.roleMethodSpec.traverse(visitor,this.scope);
			if (this.baseMethodSpec != null) // null happens on "void foo() -> ;"
				this.baseMethodSpec.traverse(visitor,this.scope);
			if(this.mappings != null)
			{
				for (int i = 0; i < this.mappings.length; i++)
				{
					ParameterMapping mapping = this.mappings[i];
					mapping.traverse(visitor,this.scope);
				}
			}
		}
		visitor.endVisit(this, classScope);
	}

	public boolean isCallin()
	{
		return false;
	}

	public boolean isCallout()
	{
		return true;
	}

	public boolean isCalloutOverride()
	{
		return this.calloutKind==TokenNameCALLOUT_OVERRIDE;
	}

    public boolean isCalloutToField()
    {
        return this.baseMethodSpec instanceof FieldAccessSpec;
    }

	public boolean canAccessInvisibleBase() {
		return ALLOW_DECAPSULATION;
	}
	/**
     * @return the start position of arrow token
     */
    public int arrowSourceStart() {
        return this.roleMethodSpec.sourceEnd + 1;
    }

    /**
     * @return the end position of arrow token
     */
    public int arrowSourceEnd() {
        return this.baseMethodSpec.sourceStart - 1;
    }

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.compiler.ast.AbstractMethodMappingDeclaration#getImpementationMethodSpec()
	 */
	public MethodSpec getImplementationMethodSpec() {
		return this.baseMethodSpec;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.compiler.ast.AbstractMethodMappingDeclaration#getBaseMethodSpecs()
	 */
	public MethodSpec[] getBaseMethodSpecs() {
		if (this.baseMethodSpec != null) {
		return new MethodSpec[] { this.baseMethodSpec };
		} else {
			tagAsHavingErrors(); // caused by a syntax error after the "->" or "=>" token.
			return new MethodSpec[0];
		}
	}

	/**
     * After a callout-rolemethod has been generated from a shorthand style callout,
     * a ProblemMethodBinding(NotFound) must be replaced with a valid method binding.
     *
	 * @param method
	 */
	public void updateRoleMethod(MethodBinding method) {
		this.roleMethodSpec.resolvedMethod = method;
		this.binding._roleMethodBinding = method;
	}
}