/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 *
 * Copyright 2004, 2006 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
 * $Id: BaseAllocationExpression.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 static org.eclipse.objectteams.otdt.core.compiler.IOTConstants.CREATOR_PREFIX_NAME;
import static org.eclipse.objectteams.otdt.core.compiler.IOTConstants._OT_BASE;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.eclipse.jdt.internal.compiler.ast.CastExpression;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Reference;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
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.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
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.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.StateHelper;
import org.eclipse.objectteams.otdt.internal.core.compiler.lifting.Lifting;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CalloutImplementorDyn;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel.UpdatableIntLiteral;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator;

/**
 * A base constructor invocation "base(args)";
 * Translated to "_OT$base = new BaseClass(args);"
 *
 * @author stephan
 * @version $Id: BaseAllocationExpression.java 23401 2010-02-02 23:56:05Z stephan $
 */
public class BaseAllocationExpression extends Assignment {

    // intermediate store, before transfering this to the AllocationExpression.
    public Expression[] arguments;
    public Expression enclosingInstance;

    public boolean isExpression = false;
    private boolean isAstCreated = false;
	private Boolean checkResult = null; // three-valued logic (incl null)

    /**
     *
     */
    public BaseAllocationExpression(int start, int end) {
        // only set the lhs yet, expression is constructed later.
        super(new SingleNameReference(_OT_BASE, 0), null, end);
        this.sourceStart = start;
    }

	@Override
	public FlowInfo analyseCode(
			BlockScope currentScope,
			FlowContext flowContext,
			FlowInfo flowInfo)
	{
		if (this.isExpression) // don't treat as assignment
			return this.expression.analyseCode(currentScope, flowContext, flowInfo);
		// in case of error assume it might relate to duplicate base() calls, don't report again.
		if (((AbstractMethodDeclaration)currentScope.methodScope().referenceContext).ignoreFurtherInvestigation)
			return flowInfo;
		return super.analyseCode(currentScope, flowContext, flowInfo);
	}

    /**
     * Initialize the type to create from the "playedBy" clause.
     * @param scope non-null
     */
    private void createAst(BlockScope scope) {
        if (this.isAstCreated) return; // already done.

        this.isAstCreated = true; // even if creation fails, don't try again.

        ReferenceBinding          enclType;
        AbstractMethodDeclaration enclMethodDecl;
        ReferenceBinding          baseclass = null;

        enclType = scope.enclosingSourceType();
        enclMethodDecl = (AbstractMethodDeclaration)scope.methodScope().referenceContext;

        if (enclType.isDirectRole())
            baseclass = ((MemberTypeBinding)enclType).baseclass();
        if (   baseclass == null
            || !enclMethodDecl.isConstructor())
        {
            scope.problemReporter().baseConstructorCallInWrongMethod(
                    this, scope.methodScope().referenceContext);
            return;
        }
        ConstructorDeclaration enclCtor = (ConstructorDeclaration)enclMethodDecl;
        if (this.isExpression) {
        	if (!isArgOfOtherCtor(enclCtor, scope))
        		scope.problemReporter().baseConstructorExpressionOutsideCtorCall(this);
        } else {
        	if (enclCtor.statements[0] != this) 
        		scope.problemReporter().baseConstructorCallIsNotFirst(this);
        }

        AstGenerator gen = new AstGenerator(this.sourceStart, this.sourceEnd);
        Expression allocation;
        if (this.enclosingInstance != null) {
        	this.enclosingInstance= new PotentialLowerExpression(this.enclosingInstance, baseclass.enclosingType());
        // FIXME(SH): check baseclass.enclosingType();
        }

        if (baseclass.isDirectRole()) {
        	// instead of new B() create:
        	// 		receiver._OT$createB():
        	Expression receiver;
        	if (RoleTypeBinding.isRoleWithExplicitAnchor(baseclass)) {
	        	RoleTypeBinding baseRole = (RoleTypeBinding)baseclass;
	        	ITeamAnchor anchor = baseRole._teamAnchor;
	        	ReferenceBinding startClass = anchor.getFirstDeclaringClass();
	        	char[][] tokens = anchor.tokens();
	        	if (startClass != null) {
	        		// relevant start class, create as receiver:
	        		//     EnclType.this.field1.
	        		TypeReference startReference = gen.typeReference(startClass);
	        		startReference.setBaseclassDecapsulation(DecapsulationState.ALLOWED);
	        		receiver = gen.qualifiedThisReference(startReference);
	        		for (int i = 0; i < tokens.length; i++) {
						receiver = gen.fieldReference(receiver, tokens[i]);
					}
	        	} else {
	        		// the best name path defines the receiver:
		        	receiver = gen.qualifiedNameReference(tokens);
	        	}
        	} else {
        		if (this.enclosingInstance != null) {
					receiver= this.enclosingInstance;
				}
				else {
					if (TypeBinding.equalsEquals(baseclass.enclosingType(), enclType.enclosingType()))
						receiver = gen.thisReference(); // creating a role of the same team as base instance??
					else
						receiver = gen.qualifiedThisReference(gen.typeReference(baseclass.enclosingType()));
				}
        	}
            char[] selector = CharOperation.concat(CREATOR_PREFIX_NAME, baseclass.sourceName());

        	MessageSend allocSend = new MessageSend() {
        		@Override
				public boolean isDecapsulationAllowed(Scope scope2) {
        			// this message send can decapsulate independent of scope
        			return true;
        		}
        		@Override
        		public DecapsulationState getBaseclassDecapsulation() {
        			return DecapsulationState.ALLOWED;
        		}
        	};
        	gen.setPositions(allocSend);
        	allocSend.receiver = receiver;
        	allocSend.selector = selector;
        	allocSend.arguments = this.arguments;
        	allocSend.accessId = -1; // request that MessageSend.resolveType() assigns a fresh accessId if decapsulation is detected
        	allocation = allocSend;
        } else {
            AllocationExpression alloc = newAllocation(baseclass, gen);
            alloc.type.setBaseclassDecapsulation(DecapsulationState.ALLOWED); // report individually
            alloc.arguments    = this.arguments;
            alloc.sourceStart  = this.sourceStart;
            alloc.sourceEnd    = this.sourceEnd;
            alloc.statementEnd = this.statementEnd;
            allocation = alloc;
        }
        this.arguments = null; // don't use any more.

        ExplicitConstructorCall selfcall = enclCtor.constructorCall;
        if (   selfcall.isImplicitSuper()
        	&& enclType.superclass().isDirectRole()
			&& enclType.superclass().baseclass() != null)
        {
        	// implement 2.4.2(c):
        	// transform "super(); base(args);" => "super(new MyBase(args)); nop;"
        	enclCtor.constructorCall = genLiftCtorCall(allocation);
        	enclCtor.statements[0] = new AstGenerator(this.sourceStart, this.sourceEnd).emptyStatement();
        	// pretend we are not calling base() because we already call the lifting-ctor.
        } else if (this.isExpression) {
        	// similar to above:
        	// translate "super(base(args), ...);" as "super(new MyBase(args), ...);"
        	this.expression = allocation; // and ignore the assignment flavor of this node.
        } else {
        	// needed by ASTConverter:
        	this.expression = allocation;
        	if (   !enclType.roleModel.hasBaseclassProblem()
        		&& !scope.referenceType().ignoreFurtherInvestigation)
        	{

	    		MethodModel.setCallsBaseCtor(enclCtor);

	    		// really creating base here, need to register this base object
	    		RoleModel boundRootRoleModel = enclType.roleModel.getBoundRootRole();
	    		if (boundRootRoleModel == null)
    				throw new InternalCompilerError("Unexpected: role has neither baseclassProblem nor boundRootRole"); //$NON-NLS-1$
	    		Statement[] regStats = Lifting.genRoleRegistrationStatements(scope,
	    																	 boundRootRoleModel,
	    																	 baseclass,
	    																	 enclCtor,
	    																	 gen);
	    		int len = enclCtor.statements.length;
	    		Statement[] newStats = new Statement[len+regStats.length];
	    		newStats[0] = this;
	    		System.arraycopy(regStats, 0, newStats, 1, regStats.length);
	    		System.arraycopy(enclCtor.statements, 1, newStats, regStats.length+1, len-1);
	    		enclCtor.setStatements(newStats);
    		}
        }
    }

	public static Expression convertToDynAccess(BlockScope scope, AllocationExpression expression, int accessId) {
		TypeBinding baseclass = expression.resolvedType;
		AstGenerator gen = new AstGenerator(expression);
    	Expression receiver = gen.typeReference(baseclass);
    	char[] selector = CalloutImplementorDyn.OT_ACCESS_STATIC;
    	int modifiers = ClassFileConstants.AccPublic|ClassFileConstants.AccStatic;
		Expression[] arguments = expression.arguments;
		Expression enclosingInstance = null;
		ReferenceBinding enclosingTeam = null;
		if (expression instanceof QualifiedAllocationExpression) {
			enclosingInstance = ((QualifiedAllocationExpression) expression).enclosingInstance;
			// TODO: enclosing team (for accessId-updating)?
		} else if (baseclass.isMemberType()) {
			// extract the enclosing base instance from an outer playedBy:
			enclosingTeam = scope.enclosingReceiverType().enclosingType();
			if (enclosingTeam != null
					&& TypeBinding.equalsEquals(baseclass.enclosingType(), enclosingTeam.baseclass)) {
				enclosingInstance = gen.fieldReference(
										gen.qualifiedThisReference(gen.typeReference(enclosingTeam)),
										IOTConstants._OT_BASE);
				enclosingInstance.resolve(scope);
			}
		}
		if (enclosingInstance != null) {
			if (arguments == null) {
				arguments = new Expression[] { enclosingInstance };
			} else {
				int len = arguments.length;
				System.arraycopy(arguments, 0, arguments = new Expression[len+1], 1, len);
				arguments[0] = enclosingInstance;
			}
		}
		MessageSend allocSend = new MessageSend() {
    		@Override
			public boolean isDecapsulationAllowed(Scope scope2) {
    			// this message send can decapsulate independent of scope
    			return true;
    		}
    		@Override
    		public DecapsulationState getBaseclassDecapsulation() {
    			return DecapsulationState.ALLOWED;
    		}
    	};
    	gen.setPositions(allocSend);
    	allocSend.receiver = receiver;
    	allocSend.selector = selector;
    	allocSend.constant = Constant.NotAConstant;
    	allocSend.actualReceiverType = baseclass;
    	allocSend.accessId = accessId;
   		allocSend.arguments = createResolvedAccessArguments(gen, accessId, arguments, enclosingTeam, scope);
    	allocSend.binding = new MethodBinding(modifiers, new TypeBinding[] {
    			TypeBinding.INT,
    			TypeBinding.INT,
    			scope.createArrayType(scope.getJavaLangObject(), 1),
    			scope.getOrgObjectteamsITeam()
    		}, 
    		Binding.NO_EXCEPTIONS,
    		(ReferenceBinding) baseclass);
    	allocSend.binding.returnType = scope.getJavaLangObject();
    	allocSend.binding.selector = selector;
    	return gen.resolvedCastExpression(allocSend, baseclass, CastExpression.RAW);
	}

	private static Expression[] createResolvedAccessArguments(AstGenerator gen, int accessId, Expression[] arguments, ReferenceBinding enclosingTeam, BlockScope scope) {
		UpdatableIntLiteral accessIdLiteral = gen.updatableIntLiteral(accessId);
		accessIdLiteral.resolveType(scope);
		if (enclosingTeam != null)
			enclosingTeam.getTeamModel().recordUpdatableAccessId(accessIdLiteral);

		IntLiteral opKindLiteral = gen.intLiteral(0);
		opKindLiteral.resolveType(scope);
		
		Expression[] boxedArgs = null;
		if (arguments != null) {
			boxedArgs = new Expression[arguments.length];
			for (int i = 0; i < arguments.length; i++) {
				Expression argument = arguments[i];
				if (argument.resolvedType.isPrimitiveType()) {
					BaseTypeBinding baseType = (BaseTypeBinding) argument.resolvedType;
					MessageSend boxingSend = gen.createBoxing(argument, baseType);
					boxingSend.resolvedType = scope.environment().computeBoxingType(baseType);
					boxingSend.binding = scope.getMethod(boxingSend.resolvedType, TypeConstants.VALUEOF, new TypeBinding[]{baseType}, boxingSend);
					boxingSend.actualReceiverType = boxingSend.resolvedType;
					boxingSend.argumentTypes = new TypeBinding[] { baseType };
					boxingSend.constant = Constant.NotAConstant;
					argument = boxingSend;
				}
				boxedArgs[i] = argument;
			}
		}
		ArrayAllocationExpression packedArgs = gen.arrayAllocation(gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT), 
				boxedArgs != null ? 1 : 0, boxedArgs); // arguments are already resolved at this point
		ArrayBinding objectArray = scope.createArrayType(scope.getJavaLangObject(), 1);
		if (packedArgs.initializer != null)
			packedArgs.initializer.binding = objectArray;
		else
			packedArgs.dimensions[0].resolveType(scope);
		packedArgs.resolvedType = objectArray;
		packedArgs.constant = Constant.NotAConstant;

		Reference teamReference = gen.qualifiedThisReference(scope.enclosingSourceType().enclosingType());
		teamReference.resolveType(scope);
		
		return new Expression[] { accessIdLiteral, opKindLiteral, packedArgs, teamReference };
	}

	private boolean isArgOfOtherCtor(ConstructorDeclaration constructorDecl, BlockScope scope) {
    	// two marker exception types:
    	@SuppressWarnings("serial") class FoundException extends RuntimeException { /*empty*/}
    	@SuppressWarnings("serial") class NotFoundException extends RuntimeException { /*empty*/ }
    	try {
    		constructorDecl.traverse(new ASTVisitor() {
    			int inCtorCall=0;
    			@Override
    			public boolean visit(ExplicitConstructorCall ctorCall, BlockScope aScope) {
    				this.inCtorCall++;
   					return super.visit(ctorCall, aScope);
    			}
    			@Override
    			public void endVisit(ExplicitConstructorCall explicitConstructor, BlockScope aScope) {
    				super.endVisit(explicitConstructor, aScope);
    				this.inCtorCall--;
    			}
    			@Override
    			public boolean visit(Assignment assig, BlockScope aScope) {
    				if (assig == BaseAllocationExpression.this) {
    					if (this.inCtorCall>0)
    						throw new FoundException();
    					else
    						throw new NotFoundException();
    				}
    				return super.visit(assig, aScope);
    			}
			},
			scope.classScope());
    	} catch (FoundException fe) {
    		return true;
    	} catch (NotFoundException nfe) {
    		return false;
    	}
    	return false;
    }

	private AllocationExpression newAllocation(ReferenceBinding baseclass, AstGenerator gen)
	{
		if (this.enclosingInstance == null) {
			AllocationExpression alloc= new AllocationExpression();
			alloc.type= gen.typeReference(baseclass);
			return alloc;
		} else {
			QualifiedAllocationExpression alloc= new QualifiedAllocationExpression();
			alloc.enclosingInstance= this.enclosingInstance;
			alloc.type= gen.singleTypeReference(baseclass.sourceName);
			return alloc;
		}
	}

    /**
	 * @param baseExpr
	 */
	private ExplicitConstructorCall genLiftCtorCall(Expression baseExpr) {
		ExplicitConstructorCall constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.Super);
		constructorCall.arguments = new Expression[] { baseExpr };
		constructorCall.sourceStart = this.sourceStart;
		constructorCall.sourceEnd   = this.sourceEnd;
		return constructorCall;
	}

	public boolean checkGenerate(BlockScope scope) {
		if (this.checkResult != null)
			return this.checkResult;
		this.checkResult = Boolean.TRUE; // preliminary, prevent re-entrance from isArgOfOtherCtor
		return this.checkResult = Boolean.valueOf(internalCheckGenerate(scope));
	}
	private boolean internalCheckGenerate(BlockScope scope) {
    	if (scope == null)
    		return false;
    	ReferenceContext referenceContext = scope.methodScope().referenceContext;
    	if (!(referenceContext instanceof AbstractMethodDeclaration)) {
    		scope.problemReporter().baseConstructorCallInWrongMethod(this, referenceContext);
    		return false;
    	}
    	AbstractMethodDeclaration enclosingMethodDeclaration = (AbstractMethodDeclaration)referenceContext;
		if (!enclosingMethodDeclaration.ignoreFurtherInvestigation)
		{
    		createAst(scope);
    		return this.expression != null;
		}
		return false;
    }

    @Override
	public void traverse(ASTVisitor visitor, BlockScope scope) {
        // we might be the first to analyse this expression:
        // (Actually triggered by TransformStatementsVisitor
    	//  - but don't do it before STATE_LENV_DONE_FIELDS_AND_METHODS,
    	//    which is needed to lookup baseclass()!)
    	TypeDeclaration enclType = (scope != null) ? scope.referenceType() : null;
    	if (   enclType != null
    		&& enclType.isDirectRole()
			&& StateHelper.hasState(enclType.binding, ITranslationStates.STATE_LENV_DONE_FIELDS_AND_METHODS))
    	{
	    	if (checkGenerate(scope)) { // only if successful:
	    		// when called from createAst->isArgOfOtherCtor we don't yet have the expression generated
	    		if (this.isExpression && this.expression != null)
	    			this.expression.traverse(visitor, scope);
	    		else
	    			super.traverse(visitor, scope);
	    	}
    	} else {
    		if (this.expression != null)
    			super.traverse(visitor, scope);
    	}
    }

    @Override
	public TypeBinding resolveType(BlockScope scope) {
    	TypeDeclaration roleDecl = scope.referenceType();
    	if (roleDecl != null && roleDecl.isRole() && roleDecl.getRoleModel()._playedByEnclosing) {
    		scope.problemReporter().baseAllocationDespiteBaseclassCycle(this, roleDecl);
    		return null;
    	}
        if (!checkGenerate(scope)) { // createAst failed.
            return null;
        }
		if (this.isExpression) // don't treat as assignment
			return this.resolvedType = this.expression.resolveType(scope);
		if (!scope.methodScope().referenceContext.hasErrors())
			return super.resolveType(scope);
		return null;
    }
    
    @Override
    public void computeConversion(Scope scope, TypeBinding runtimeType, TypeBinding compileTimeType) {
    	if (this.isExpression)
    		this.expression.computeConversion(scope, runtimeType, compileTimeType);
    	else
    		super.computeConversion(scope, runtimeType, compileTimeType);
    }

    @Override
    public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
		if (this.isExpression) // don't treat as assignment
			this.expression.generateCode(currentScope, codeStream, valueRequired);
		else
			super.generateCode(currentScope, codeStream, valueRequired);
    }
    
    @Override
	public String toString() {
        if (this.expression == null)
            return "unresolved base() call"; //$NON-NLS-1$
        return this.expression.toString();
    }

    @Override
	public StringBuffer printExpression (int indent, StringBuffer output) {
    	if (this.expression != null)
    		return super.printExpression(indent, output);
    	return output.append("<no expression yet>"); //$NON-NLS-1$
    }

	@Override
	public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
    	if (this.expression != null)
    		return super.printExpressionNoParenthesis(indent, output);
    	return output.append("<no expression yet>"); //$NON-NLS-1$
	}
}
