/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 *
 * Copyright 2004, 2016 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.model;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions.WeavingScheme;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.CPTypeAnchorAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.OTSpecialAccessAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.ReferencedTeamsAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.RoleFilesAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.WordValueAttribute;
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.control.StateMemento;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
import org.eclipse.objectteams.otdt.internal.core.compiler.smap.LineNumberProvider;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;

/**
 * Generalizes TeamModel and RoleModel
 * @author stephan
 */
public class TypeModel extends ModelElement {

    /* Constructor for regular instances. */
    public TypeModel (TypeDeclaration ast) {
        this._ast = ast;
    	int[] lineSeparatorPositions = ast.compilationResult.lineSeparatorPositions;
    	if (lineSeparatorPositions != null) {
    		this._maxLineNumber = Util.getLineNumber(ast.declarationSourceEnd, lineSeparatorPositions, 0, lineSeparatorPositions.length-1);
    	} else if (   !ast.isConverted
    		 	   && !ast.isGenerated
				   && Dependencies.needMethodBodies(ast))
    	{
    		throw new InternalCompilerError("Unexpectedly missing line number information");  //$NON-NLS-1$
    	}
    	this._state = new StateMemento();
    }
    /* Constructor for regular instances. */
    public TypeModel (ReferenceBinding bind) {
        this._binding = bind;
    	this._state = new StateMemento();
    }
    /** clone constructor: */
    public TypeModel (TypeModel prototype, ReferenceBinding protoBinding) {
    	this._binding = protoBinding;
    	this._state = prototype._state;
    	this._compilerVersion = prototype._compilerVersion;
    	this.weavingScheme = prototype.weavingScheme;
    	this._ast = prototype._ast;
    }

    /** Store the byte code attribute which maps constant pool entries (Class_info) to type anchors. */
    private CPTypeAnchorAttribute _typeAnchors;

    /** Mediate RoleFilesAttribute to RoleFileCache. */
    public RoleFilesAttribute _roleFilesAttribute = null;

    /** Backward reference for the Ast being wrapped. */
	protected TypeDeclaration _ast;

	protected ReferenceBinding _binding;

    private HashSet<ReferenceBinding> _referencedTeams = null;

    /** translation state of this model element */
    final public StateMemento _state;

    /** Record here all types which are defined local to a method (TypeDeclaration). */
    private LinkedList<TypeDeclaration> _localPlainTypes = new LinkedList<TypeDeclaration>();

    public int _maxLineNumber = 0;

    /**
     * Needed for JSR-045 support.
	 * Can be asked for new line numbers(above linenumberrange) and stores mapping.
	 */
	protected LineNumberProvider _lineNumberProvider;

	/**
	 * Version number of the compiler that created a (binary) type;
	 */
	public int _compilerVersion;

	WeavingScheme weavingScheme;

	public void setCompilerVersion(int version, WeavingScheme weavingScheme) {
		this._compilerVersion = version;
		this.weavingScheme = weavingScheme;
	}

	public void setBinding (ReferenceBinding binding) {
        this._binding = binding;
        binding.model = this;
    }
	/**
	 * @return The class-part of the AST being wrapped. May be null!!
	 */
	public TypeDeclaration getAst() {
		return this._ast;
	}
	public ReferenceBinding getBinding() {
		if (this._binding == null && this._ast != null && this._ast.binding != null)
			setBinding(this._ast.binding);
		return this._binding;
	}

    /**
     * Get all members which are not roles represented by their TypeModel.
     * Considers Ast or Bindings, whatever is more appropriate.
     * Note, that members could again be teams.
     *
     * @returns all members for this Team.
     */
    public TypeModel[] getMembers()
    {
        List<TypeModel> list = new LinkedList<TypeModel>();

        if(this._ast == null)
        {
        	if (   this._binding.kind() == Binding.TYPE_PARAMETER
        		|| this._binding.kind() == Binding.WILDCARD_TYPE
        		|| this._binding.kind() == Binding.INTERSECTION_TYPE
        		|| this._binding.kind() == Binding.INTERSECTION_TYPE18)
        		return new TypeModel[0]; // has no members

        	if (this._binding.isUnresolvedType())
        		return new TypeModel[0]; // members unknown and cannot resolve here :(

        	//binary type
        	assert this._binding.isBinaryBinding();
        	// don't used memberTypes() as not to trigger resolving unneeded members.
        	// see tests.compiler.regegression.LookupTest.test044
            ReferenceBinding[] memberBindings = ((BinaryTypeBinding)this._binding).unresolvedMemberTypes();
            for (int i = 0; i < memberBindings.length; i++)
            {
                ReferenceBinding binding = memberBindings[i];
                if (binding instanceof UnresolvedReferenceBinding)
                	continue; // has no model yet cannot handle yet.
                if (binding.isTeam())
                    list.add(binding.getTeamModel());
                else
                    list.add(binding.model);
            }
        }
        else
        {
            TypeDeclaration[] members = this._ast.memberTypes;
            if (members != null)
            {
                for (int idx = 0; idx<members.length; idx++)
                {
                    TypeDeclaration decl = members[idx];
                    if (decl.isTeam())
                        list.add(decl.getTeamModel());
                    else if (decl.isRole())
                    	list.add(decl.getRoleModel());
                    else
                        list.add(decl.getModel());
                }
            }

            AbstractMethodDeclaration[] methods = this._ast.methods;
            if (methods != null) {
                for (int i=0; i<methods.length; i++) {
                    if (methods[i] != null && methods[i].scope != null) {
                        ClassScope[] scopes = methods[i].scope.getAllLocalTypes();
                        for (int j=0; j<scopes.length; j++) {
                            TypeDeclaration type = scopes[j].referenceContext;
                            if (type.isTeam()) // very unlikely ;-)
                                list.add(type.getTeamModel());
                            else if (type.isRole())
                            	list.add(type.getRoleModel());
                            else
                                list.add(type.getModel());
                        }
                    }
                    // no scope could mean:
                    // 1. it's a <clinit>
                    // 2. we are before scope creation
                    //    (which happens in completeTypeBindings(), last step of beginToCompile).
                    // This is ok, since then we only miss step RoleSplitter, but local types
                    // cannot be teams with roles anyway.
                }
            }
        }
        return list.toArray(new TypeModel[list.size()]);
    }

    public ReferenceBinding findType(LookupEnvironment environment, char[][] compoundName) {
		char[][] myName = CharOperation.splitOn('/', this._binding.constantPoolName());
		if (   this._binding.isLocalType()
			&& CharOperation.equals(compoundName, myName))
			return this._binding;
		if (   this._binding.enclosingType() != null
			&& this._binding.enclosingType().isRole())
			return this._binding.enclosingType().roleModel.findType(environment, compoundName);
		return environment.getType(compoundName);
    }

    public char[] getInternalName() {
        if (this._ast != null)
            return this._ast.name;
        else
            return this._binding.internalName();
    }


    public void cleanup() {
        this._ast = null;
        this._lineNumberProvider = null;
    }

    public void addLocalType(TypeDeclaration localType) {
    	this._localPlainTypes.add(localType);
    }

    // === state handling: ===

	public int getState() {
		return this._state.getState();
	}

    /**
     * Include local types in set state.
     */
    public int setState(int state) {
    	int oldState= this._state.setState(state);
    	for (TypeDeclaration localType : this._localPlainTypes)
    		if (localType.getModel().getState() >= ITranslationStates.STATE_RESOLVED)
    			localType.getModel().setState(state);
    	this._state.runPendingJobs(state);
    	return oldState;
    }

	public void setMemberState(int state) {
        TypeModel[] members = getMembers();
        if (members != null)
        {
            for (int i=0; i<members.length; i++)
            {
                TypeModel member = members[i];
                member.setMemberState(state);
                member.setState(state);
            }
        }
    }

	public boolean isReadyToProcess(int state) {
		return this._state.isReadyToProcess(state);
	}

    public boolean isTeam() {
        return false;
    }
	public boolean isRole() {
		if (this._binding != null)
			return this._binding.isRole();
		return this._ast.isRole();
	}

	protected String getKindString() {
        return "Class "; //$NON-NLS-1$
	}

	@Override
	@SuppressWarnings("nls")
	public String toString() {
		String name = (this._ast != null) ?
				new String(this._ast.name) :
				new String(this._binding.sourceName());
		return   getKindString()+" "+name
		       + " (state: " + this._state +")";
	}

    /**
     * Check whether a binding found by getTypeOrPackage is a team,
     * and if so, record it as a referenced team of this type.
     *
     * @param binding
     * @param scope site where reference was found
     */
    public static void checkReferencedTeam(Binding binding, Scope scope) {
        if (!(binding instanceof ReferenceBinding))
            return;
        ReferenceBinding type = (ReferenceBinding)binding;
        if (!type.isTeam())
            return;
        // is binding an enclosing type of scope?
        ReferenceBinding currentType = scope.enclosingSourceType();
    	while (currentType != null) {
			if (currentType == binding)
				return; // no need to record self-reference
			currentType = currentType.enclosingType();
    	}
    	while (scope != null) {
			TypeDeclaration site = scope.referenceType();
			if (site == null)
				return;
			site.getModel().registerReferencedTeam(type);
			scope = scope.parent;
    	}
    }

    /**
     * Mark that the current class references the given team type.
     * @param teamType
     */
    private void registerReferencedTeam(ReferenceBinding teamType) {
    	if (TypeAnalyzer.isOrgObjectteamsTeam(teamType))
    		return; // optimize since Team has no bindings.
        if (this._referencedTeams == null) {
            this._referencedTeams = new HashSet<ReferenceBinding>();
            addAttribute(new ReferencedTeamsAttribute(this));
        }
        this._referencedTeams.add(teamType);
    }

    /**
     * Retrieve the gathered data about referenced teams.
     * @return Object[] containing ReferenceBindings
     */
    public ReferenceBinding[] getReferencedTeams() {
        return this._referencedTeams.toArray(new ReferenceBinding[this._referencedTeams.size()]);
    }

    public boolean isIgnoreFurtherInvestigation() {
    	if (this._ast == null)
    		return false;
    	return TypeModel.isIgnoreFurtherInvestigation(this._ast);
    }
    public static boolean isIgnoreFurtherInvestigation(TypeDeclaration type)
    {
    	if (type.ignoreFurtherInvestigation)
    		return true;
    	if (   type.compilationUnit != null
    		&& type.compilationUnit.ignoreFurtherInvestigation)
    		return true;
    	if (   type.scope != null
    		&& type.scope.cuIgnoreFurtherInvestigation())
        	return true;
    	if (   type.enclosingType != null
    		&& type.enclosingType.ignoreFurtherInvestigation)
    		return true;
    	if((type.bits & ASTNode.IsLocalType)!=0 && type.scope != null) {
    		MethodScope outerMostMethodScope = type.scope.outerMostMethodScope();
    		if (outerMostMethodScope != null) {
    			if (outerMostMethodScope.referenceContext instanceof AbstractMethodDeclaration)
    			{ // weired: MethodScope.referenceContext can be a TypeDeclaration!?!
    				AbstractMethodDeclaration method = (AbstractMethodDeclaration)outerMostMethodScope.referenceContext;
    				if (   method != null
    				    && method.ignoreFurtherInvestigation)
    					return true;
    			}
    		}
    	}
    	return false;
    }

    /**
     * Has this type been compiled with an old compiler,
     * meaning byte code is not compatible to current commpiler?
     *
     * Should only be used when a problem has already been detected,
     * because we might be over-cautious here which means a <code>true</code>
     * answer from this method does not necessarily imply actual incompatibility.
     */
    public boolean isIncompatibleCompilerVersion() {
    	// require major and minor to match the current compiler, for now.
		int minVersion =    (IOTConstants.OTVersion.getMajor() << 9)
						  + (IOTConstants.OTVersion.getMinor() << 5);
		return this._compilerVersion < minVersion;
	}

	public CPTypeAnchorAttribute getTypeAnchors() {
    	return this._typeAnchors;
    }
	/**
	 * Note: this setter is overridden in RoleModel
	 */
	public void setTypeAnchors(CPTypeAnchorAttribute attribute) {
		this._typeAnchors = attribute;
	}
	public void addTypeAnchor(ITeamAnchor anchor, int cpIndex) {
		if (this._typeAnchors == null) {
			this._typeAnchors = new CPTypeAnchorAttribute();
			addAttribute(this._typeAnchors);
		}
		this._typeAnchors.addTypeAnchor(anchor, cpIndex);
	}

	/**
	 * Some attributes can only be evaluated after translation reaches a specific state
	 *	at end of FAULT_IN_TYPES:
	 *	    CallinMethodMappingAttribute, CalloutMethodMappingAttribute
	 * 	task of LATE_ATTRIBUTES_EVALUATED:
	 *	    CopyInheritanceSrc (roles)
	 *	    CallinPrecedence (teams)
	 */
	public void evaluateLateAttributes(int state) {
		try {
			try {
				if (this._binding != null && this._binding.isBinaryBinding()) {
					if (this._attributes != null) {
						for (int i = 0; i < this._attributes.length; i++) {
							this._attributes[i].evaluateLateAttribute(this._binding, state);
						}
					}
				}
			} catch (AbortCompilation ac) {
				// abort may e.g. happen if a binary tsuper role is inconsistent.
				TypeDeclaration type = this._ast;
				if (type == null) {
					ReferenceBinding enclosing = this._binding.enclosingType();
					if (enclosing != null && !enclosing.isBinaryBinding())
						type = enclosing.model.getAst();
				}
				if (type != null)
					ac.updateContext(type, type.compilationResult);
				throw ac;
			}
			if (this._binding != null) {
				ReferenceBinding[] memberTypes = this._binding.memberTypes();
				if (memberTypes != null) {
					for (int i = 0; i < memberTypes.length; i++) {
						ModelElement.evaluateLateAttributes(memberTypes[i], state);
					}
				}
			}
		} finally {
			// don't advance the state when working on behalf of another state
			if (state == ITranslationStates.STATE_LATE_ATTRIBUTES_EVALUATED)
				setState(ITranslationStates.STATE_LATE_ATTRIBUTES_EVALUATED);
		}
	}
	// ====  allow to re-read bytes from the written class file ====
	// See comment in ClassFile (near field "generatingModel").

	protected String _classFilePath = null;

	/** Store different elements accessed by this class, which require special treatment:
	 *  methods and base-classes requiring decapsulation.
	 *  fields requiring a getter and/or setter.
	 */
	protected OTSpecialAccessAttribute _specialAccess = null;

	/**
	 * @param classFilePath
	 */
	public void setClassFilePath(String classFilePath) {
		this._classFilePath = classFilePath;
	}
	public ClassFileReader read () throws IOException, ClassFormatException
	{
		if (this._classFilePath != null) {
			FileNotFoundException fileNotFoundException = null;
			for (int i=0; i<5; i++) { // make <= 5 attempts thus waiting <= 500 ms
				try {
					return ClassFileReader.read(this._classFilePath); // not recording attributes
				} catch (FileNotFoundException ex) {
					fileNotFoundException = ex;
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
			if (fileNotFoundException != null)
				throw fileNotFoundException;
		}
		return null;
	}
	/**
	 * supports CALLIN_METHOD_MAPPINGS_ATTRIBUTE and STATE_REPLACE_BINDINGS_ATTRIBUTE
	 * @param superDeclaringType represents the type from which the attribute is being copied
	 * @param attributeName
	 */
	public void copyAttributeFrom(TypeModel superDeclaringType, char[] attributeName) {
		if (superDeclaringType._attributes == null)
			return;
		for (int i = 0; i < superDeclaringType._attributes.length; i++) {
			if (superDeclaringType._attributes[i].nameEquals(attributeName)) {
				addOrMergeAttribute(superDeclaringType._attributes[i]);
				return;
			}
		}
	}

	public void setSpecialAccess(OTSpecialAccessAttribute attribute) {
		assert this._specialAccess == null;
		this._specialAccess = attribute;
	}
	public OTSpecialAccessAttribute getSpecialAccessAttribute() {
		if (this._specialAccess == null) {
			this._specialAccess = new OTSpecialAccessAttribute(this._binding, getWeavingScheme());
			addAttribute(this._specialAccess);
		}
		return this._specialAccess;
	}

	public LineNumberProvider getLineNumberProvider() {
	    if (this._lineNumberProvider == null)
	        this._lineNumberProvider = new LineNumberProvider(this._binding, this._maxLineNumber);
	    return this._lineNumberProvider;
	}

	public static LineNumberProvider getLineNumberProvider(TypeDeclaration type) {
		if (type.isRole())
			return type.getRoleModel().getLineNumberProvider();
		if (type.isTeam())
			return type.getTeamModel().getLineNumberProvider();
		return type.getModel().getLineNumberProvider();
	}

	public static boolean isConverted(ReferenceBinding declaringClass) {
		TypeDeclaration result;
		if (declaringClass instanceof SourceTypeBinding) {
			Scope scope = ((SourceTypeBinding) declaringClass).scope;
			if (scope != null && scope.referenceType() != null)
				return scope.referenceType().isConverted;
		}
		// TODO(SH): the rest of this method is probably obsoleted the above
		if (declaringClass.isRole()) {
			RoleModel roleModel = declaringClass.roleModel;
			if (roleModel != null) {
				if (  (result = roleModel.getClassPartAst()) != null
					&& result.isConverted)
					return true;
				if (  (result = roleModel.getInterfaceAst()) != null
					&& result.isConverted)
					return true;
			}
		}
		if (declaringClass.isTeam()) {
			TeamModel teamModel = declaringClass.getTeamModel();
			if (teamModel != null) {
				if (  (result = teamModel.getAst()) != null
					&& result.isConverted)
					return true;
			}
		}
		return false;
	}
	public WeavingScheme getWeavingScheme() {
		if (this.weavingScheme == null && this._ast != null && this._ast.scope != null) {
			this.weavingScheme = this._ast.scope.compilerOptions().weavingScheme;
			if (this.weavingScheme == WeavingScheme.OTDRE) {
				if (this._attributes != null)
					for (int i = 0; i < this._attributes.length; i++)
						if (this._attributes[i].nameEquals(IOTConstants.OT_COMPILER_VERSION)) {
							((WordValueAttribute)this._attributes[i]).setWeavingScheme(this.weavingScheme);
							break;
						}
			}
		}
		return this.weavingScheme;
	}
}
