/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 * 
 * Copyright 2004, 2012 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute for Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany, and others.
 * 
 * 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
 * 
 * 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;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.core.JavaModelStatus;
import org.eclipse.jdt.internal.core.TypeParameter;
import org.eclipse.jdt.internal.core.util.Util;
import org.eclipse.objectteams.otdt.core.IMethodMapping;
import org.eclipse.objectteams.otdt.core.IOTJavaElement;
import org.eclipse.objectteams.otdt.core.IOTType;
import org.eclipse.objectteams.otdt.core.IRoleType;
import org.eclipse.objectteams.otdt.core.OTModelManager;
import org.eclipse.objectteams.otdt.core.TypeHelper;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.osgi.util.NLS;

/**
 * IRoleType implementation
 * 
 * @author jwloka
 */
public class RoleType extends OTType implements IRoleType
{
    private IType  baseClass;
    private String _baseAnchor;
    private String baseClassName;

	public RoleType(IType correspondingJavaType,
					IJavaElement parent,
					int flags,
					String baseClassName,
					String baseClassAnchor)
    {
        super(ROLE | (TypeHelper.isTeam(flags) ? TEAM : 0), correspondingJavaType, parent, flags);
        this.baseClassName = baseClassName;
        this._baseAnchor= baseClassAnchor;
    }

    /**
	 * A role's team is represented by the element's team 
	 */
    @Override
	public IOTType getTeam()
    {
    	// try directly within OT-Model:
    	if (this.parent != null && this.parent instanceof IOTType)
    		return (IOTType)this.parent;
    	// try a detour through Java-Model:
    	IType teamType = getTeamJavaType();
        if (teamType != null)
	    	return OTModelManager.getOTElement(teamType);
        // nope.
        return null;
    }
    
    @Override
	public IType getTeamJavaType() {
    	return ((IType)getCorrespondingJavaElement()).getDeclaringType();
    }

	@Override
	public IMethodMapping[] getMethodMappings()
	{
		return getMethodMappings(CALLINS | CALLOUTS);
	}

	/**
	 * @param type An ORed combination of IRoleType.CALLINS and IRoleType.CALLOUTS 
	 */
	@Override
	public IMethodMapping[] getMethodMappings(int type)
	{
		List<IMethodMapping> result   = new LinkedList<IMethodMapping>();
		if ((type & CALLINS) != 0) {	// callins from the RoleType:
			filterMethodMappings(getChildren(), CALLINS, result);
		}
		if ((type & CALLOUTS) != 0) {	// callouts from the regular IType
			try {
				filterMethodMappings(((IType)getCorrespondingJavaElement()).getChildren(), CALLOUTS, result);
			} catch (JavaModelException ex) {
            	Util.log(ex,
                		NLS.bind("Retrieving callouts of role class ''{0}'' failed!", new Object[] {getElementName()})); //$NON-NLS-1$
			}
		}
		
		return result.toArray(new IMethodMapping[result.size()]);
	}
	
	private void filterMethodMappings(IJavaElement[] children, int type, List<IMethodMapping> result) {
		for (int idx = 0; idx < children.length; idx++) {
			if (children[idx] instanceof IMethodMapping) {
				IMethodMapping mapping = (IMethodMapping) children[idx];
				switch(mapping.getElementType()) {
					case IOTJavaElement.CALLIN_MAPPING:
					    if ((type & CALLINS) != 0)
					        result.add(mapping);
					    break;
					case IOTJavaElement.CALLOUT_MAPPING:
					    if ((type & CALLOUTS) != 0)
					        result.add(mapping);
					    break;
                    case IOTJavaElement.CALLOUT_TO_FIELD_MAPPING:
                        if ((type & CALLOUTS) != 0)
                            result.add(mapping);
                        break;
				}
			}
		}
	}

	@Override
	public boolean isRoleFile()
	{
	    return false;
	}
	
	public void setBaseClass(IType baseClass)
	{
		this.baseClass = baseClass;
	}

	@Override
	public IType getBaseClass() throws JavaModelException {
		return getBaseClass(null);
	}
	private IType getBaseClass(ITypeHierarchy hierarchy) throws JavaModelException
	{
		if (this.baseClass == null)
		{
			JavaModelException jex = null;
			
			try
            {
//			    System.out.println("RoleType.getBaseClass(): " + getElementName());
                this.baseClass = findBaseClass(hierarchy);
            }
			catch (JavaModelException ex)
			{
				jex = ex;
			}
            catch (Exception ex)
            {
            	// just be sure we get all kind of exceptions
            	Util.log(ex,
            		NLS.bind("Resolving of base class ''{0}'' failed!", new Object[] {this.baseClassName})); //$NON-NLS-1$
            }

            // when having syntax/compilation errors, we can't ensure to find our baseclass
            if (this.baseClass == null && (this.baseClassName != null || jex != null))
            {
            	IStatus status = new Status(
            			IStatus.WARNING, 
						JavaCore.PLUGIN_ID, 
						IStatus.OK, 
            			NLS.bind("Base class for role {0} not found.",  //$NON-NLS-1$
							new Object[] { getTypeQualifiedName('.') }),
						jex
            			);
            	throw new JavaModelException(new CoreException(status));
            }
		}
		
		return this.baseClass;
	}
	
	@Override
	public String getBaseclassName() {
	    if (this._baseAnchor != null)
	        return this._baseAnchor + '.' + this.baseClassName;
		return this.baseClassName;
	}

	@Override
	public String getFullBaseclassName() {
		if (this._baseAnchor == null || this._baseAnchor.length() == 0)
			return this.baseClassName;
		return this.baseClassName+"<@"+this._baseAnchor+">"; //$NON-NLS-1$ //$NON-NLS-2$
	}

	@Override
	public boolean equals(Object obj)
	{
		if(!(obj instanceof RoleType))
		{
		    return false;
		}

		RoleType other = (RoleType)obj;
		
		// only compare base class name, resolving the class is too expensive and unnecessary.
		if ((this.baseClassName==null) != (other.baseClassName==null))
		{
			return false;
		}
		if (this.baseClassName != null && !this.baseClassName.equals(other.baseClassName)) 
		{
			return false;
		}
		
	    return super.equals(other);
	}
	
    @Override
	@SuppressWarnings("nls")
	public String toString()
	{
		return "role " + getElementName() + " for type: " + getCorrespondingJavaElement().toString();
	}

	/**
	 * Tries to resolve this role's base class in the JavaModel.
	 * 
	 * @return resolved JavaModel type or null if nothing found 
	 */
    private IType findBaseClass(ITypeHierarchy hierarchy) throws JavaModelException
    {
        if (this.baseClassName == null)
            return findSuperBaseClass(hierarchy);
        
        if (this._baseAnchor != null)
        {
            IOTType baseAnchorType = resolveBaseAnchor();
            if (baseAnchorType == null)
                return null;
            
            // lookup via the anchor needs simple name:
            String simpleBaseName = this.baseClassName;
            int dotpos = this.baseClassName.lastIndexOf('.');
            if (dotpos != -1)
            	simpleBaseName = this.baseClassName.substring(dotpos+1);
            
            IType[] baseClasses = baseAnchorType.getRoleTypes(IOTType.ALL, simpleBaseName);
            if (baseClasses.length >= 1)
                return baseClasses[0]; // the bottom-most in the hierarchy
        }
        // resolve relative to the current type:
        return resolveInType(this, this.baseClassName);
    }

    // argument avoids recursive building of hierarchy through getBaseClass -> findSuperBaseClass -> getBaseOf -> tsuper.getBaseClass()
    private IType findSuperBaseClass(ITypeHierarchy hierarchy) throws JavaModelException
    {
        IType currentType = (IType)getCorrespondingJavaElement();
        if (hierarchy == null)
        	hierarchy = currentType.newSupertypeHierarchy(new NullProgressMonitor());
		currentType = hierarchy.getSuperclass(currentType);
		while (currentType != null && OTModelManager.isRole(currentType)) {
            IType baseType = getBaseOf(currentType, hierarchy);
            if (baseType != null)
                return baseType;
            currentType = hierarchy.getSuperclass(currentType); // relies on OTTypeHierarchies whereby getSuperclass() produces the full (t)super linearization 
        }
		return null;
    }

    private IType getBaseOf(IType type, ITypeHierarchy hierarchy) throws JavaModelException
    {
        if (type != null && type.exists())
        {
            IOTType otType = OTModelManager.getOTElement(type);
            if (otType == null) // i.e. non-role superclass
                return null;
            
            if (otType.isRole())
            {
                RoleType tsuperRole = (RoleType) otType;
                IType tsuperBase = tsuperRole.getBaseClass(hierarchy);
                if (tsuperBase != null)
                    return tsuperBase;
            }
        }
        
        return null;
    }

    private IOTType resolveBaseAnchor() throws JavaModelException
    {
        if (this._baseAnchor == null)
            return null;
        
        IOTType enclosingTeam = getTeam();
        if (enclosingTeam == null || !enclosingTeam.exists())
            return null;
        
        IType currentType= enclosingTeam;
        String anchorField= this._baseAnchor;
        int pos= this._baseAnchor.lastIndexOf('.');
        if (pos>0) {
        	anchorField= this._baseAnchor.substring(pos+1);
        	currentType= resolveInType(enclosingTeam, this._baseAnchor.substring(0, pos));
        }

        IType anchorType = null;
        if (anchorField.equals(new String(IOTConstants.BASE))) // enclosing is a role itself, 'base' is its base instance
        {
        	IOTType currentOTType= OTModelManager.getOTElement(currentType);
            if (currentOTType == null || !currentOTType.isRole())
                return null;

            IRoleType enclosingRole = (IRoleType)currentOTType;
            assert(enclosingRole != this);
            
            anchorType = enclosingRole.getBaseClass();
        }
        else
        {
	        IField field = currentType.getField(anchorField);
	        String fieldType = null;
	        if (field.exists()) {
	        	fieldType = Signature.toString(field.getTypeSignature());
	        } else {
	        	// try value parameter instead:
	        	for (ITypeParameter param : currentType.getTypeParameters()) {
	        		if (((TypeParameter)param).isValueParameter) {
	        			if (param.getElementName().equals(anchorField)) {
	        				fieldType = param.getBounds()[0]; // FIXME(SH): one value param only
	        				break;
	        			}
	        		}
	        	}
	        }
	        if (fieldType != null)
	        	anchorType = resolveInType(enclosingTeam, fieldType);
        }
        
        if (anchorType == null || !anchorType.exists())
            return null;

        return OTModelManager.getOTElement(anchorType);
    }
    
    IType resolveInType(IOTType referenceType, String type) throws JavaModelException
    {
    	// perform a search by name in the scope of this type
    	String[][] qualifiedTypes = referenceType.resolveType(type);

    	// class name must exist and be unique
		if ((qualifiedTypes != null) && (qualifiedTypes.length == 1))
		{
			String fqBaseName = Util.concatenateName(qualifiedTypes[0][0], qualifiedTypes[0][1], '.');
			// get JavaModel element by resolved name
			return referenceType.getJavaProject().findType(fqBaseName);			
		}
        
		return null;
    }
    
    @Override
	public IType[] getTSuperRoles() throws JavaModelException {
    	ArrayList<IType> tsuperRoles = new ArrayList<IType>();
    	IOTType teamType = getTeam();
    	if (teamType == null)
    		throw new JavaModelException(new JavaModelStatus(IStatus.ERROR, "Enclosing team not found for "+this.getElementName()+" perhaps this element is not on the build path?")); //$NON-NLS-1$ //$NON-NLS-2$
    	String superteamName = teamType.getSuperclassName();
    	if (superteamName != null) {
    		if (superteamName.indexOf('.') != -1) {
    			// have qualifed super team name, find it directly:
    			IType superTeam = getJavaProject().findType(superteamName);
    			if (superTeam != null) {
    				IType tsuperRole = superTeam.getType(getElementName());
    				if (tsuperRole != null && tsuperRole.exists()) {
    					this.flags |= ExtraCompilerModifiers.AccOverriding;
    					tsuperRoles.add(tsuperRole);
    				}
    			}
    		} else {
    			// only have a simply super team name, resolve it now:
				String[][] resolvedSuperTeams = teamType.resolveType(superteamName);
		    	if (resolvedSuperTeams != null)
		    		for (String[] resolvedSuperTeam : resolvedSuperTeams)
						checkAddTSuperRole(resolvedSuperTeam[0]+'.'+resolvedSuperTeam[1], tsuperRoles);
    		}
    	}
    	// no direct tsuper, search in tsuper-team if some exist:
    	if (teamType.isRole())
    		for (IType tsuperTeam : ((IRoleType)teamType).getTSuperRoles()) 
    			checkAddTSuperRole(tsuperTeam.getFullyQualifiedName('.'), tsuperRoles);
    	return tsuperRoles.toArray(new IType[tsuperRoles.size()]);
    }
    private void checkAddTSuperRole(String qualifiedTeamName, ArrayList<IType> tsuperRoles) throws JavaModelException {
		IType tsuperRole= getJavaProject().findType(qualifiedTeamName+'.'+getElementName());
		if (tsuperRole != null) {
			// in case the client was only interested in the fact that we have a tsuper role
			// store this flag to avoid duplicate search for tsuper roles:
			this.flags |= ExtraCompilerModifiers.AccOverriding;
			tsuperRoles.add(tsuperRole);
		}
    }
}

//private IMethod getMethod() {
//	ITextSelection textSelection= getTextSelection();
//	IEditorInput input = getActiveEditor().getEditorInput();
//	ICodeAssist codeAssist = null;
//	Object element = JavaUI.getWorkingCopyManager().getWorkingCopy(input);
//	if (element == null) {
//		element = input.getAdapter(IClassFile.class);
//	}
//	if (element instanceof ICodeAssist) {
//		codeAssist = ((ICodeAssist)element);
//	} else {
//		// editor does not support code assist
//		showErrorMessage(ActionMessages.getString("StepIntoSelectionActionDelegate.Step_into_selection_only_available_for_types_in_Java_projects._1")); //$NON-NLS-1$
//		return null;
//	}
//	
//	IMethod method = null;
//	try {
//		IJavaElement[] resolve = codeAssist.codeSelect(textSelection.getOffset(), 0);
//		for (int i = 0; i < resolve.length; i++) {
//			IJavaElement javaElement = resolve[i];
//			if (javaElement instanceof IMethod) {
//				method = (IMethod)javaElement;
//				break;
//			}
//		}
//	} catch (CoreException e) {
//		JDIDebugPlugin.log(e);
//	}
//	if (method == null) {
//		// no resolved method
//		showErrorMessage(ActionMessages.getString("StepIntoSelectionActionDelegate.No_Method")); //$NON-NLS-1$
//	}
//	return method;
//}
