/*******************************************************************************
 * Copyright (c) 2008 SAP AG 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
 *
 * Contributors:
 * Kaloyan Raev, kaloyan.raev@sap.com - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.common.operations;

import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.ABSTRACT_METHODS;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.CLASS_NAME;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.CONSTRUCTOR;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.INTERFACES;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.JAVA_PACKAGE;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.MODIFIER_ABSTRACT;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.MODIFIER_FINAL;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.MODIFIER_PUBLIC;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.PROJECT;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.SUPERCLASS;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;

public class CreateJavaEEArtifactTemplateModel {
	
	/**
	 * Constant representing no compatibility flag.
	 */
	public static final int FLAG_NONE = 0x00000000;
	
	/**
	 * Constant representing the <i>Qualified Superclass Name</i> compatibility
	 * flag.
	 * 
	 * <p>
	 * When this flag is set then the {@link #getSuperclassName()} method always
	 * returns the qualified name of the superclass.
	 * </p>
	 * 
	 * @see #getSuperclassName()
	 */
	public static final int FLAG_QUALIFIED_SUPERCLASS_NAME = 0x00000001;
	
	/**
	 * Constant representing a combination of all possible compatibility flags.
	 */
	public static final int FLAG_ALL = 0xffffffff;
	
	/**
	 * Compatibility flags. 
	 * 
	 * @see #addFlags(int)
	 * @see #removeFlags(int)
	 * @see #FLAG_NONE
	 * @see #FLAG_QUALIFIED_SUPERCLASS_NAME
	 * @see #FLAG_ALL
	 */
	protected int flags; 
	
	protected IDataModel dataModel;
	
	public CreateJavaEEArtifactTemplateModel(IDataModel dataModel) {
		this.dataModel = dataModel;
		this.flags = FLAG_QUALIFIED_SUPERCLASS_NAME;
	}
	
	/**
	 * Adds compatibility flags represented by the given bitmask.
	 * 
	 * @param bitmask -
	 *            represents the flags to add.
	 *            
	 * @see #addFlags(int)
	 * @see #removeFlags(int)
	 * @see #FLAG_NONE
	 * @see #FLAG_QUALIFIED_SUPERCLASS_NAME
	 * @see #FLAG_ALL
	 */
	public void addFlags(int bitmask) {
		flags = flags | bitmask;
	}
	
	/**
	 * Removes compatibility flags represented by the given bitmask.
	 * 
	 * @param bitmask -
	 *            represents the flags to remove.
	 *            
	 * @see #addFlags(int)
	 * @see #removeFlags(int)
	 * @see #FLAG_NONE
	 * @see #FLAG_QUALIFIED_SUPERCLASS_NAME
	 * @see #FLAG_ALL
	 */
	public void removeFlags(int bitmask) {
		flags = flags & ~bitmask;
	}
	
	/**
	 * Check if compatibility flags, represented by the given bitmask, are set.
	 * 
	 * @param bitmask -
	 *            represents the flags to check.
	 * 
	 * @return <code>true</code> - if all of the given flags are set,
	 *         <code>false</code> - if any of the given flags is not set.  
	 *            
	 * @see #addFlags(int)
	 * @see #removeFlags(int)
	 * @see #FLAG_NONE
	 * @see #FLAG_QUALIFIED_SUPERCLASS_NAME
	 * @see #FLAG_ALL
	 */
	public boolean areFlagsSet(int bitmask) {
		return (flags & bitmask) != 0;
	}
	
	public Collection<String> getImports() {
		Collection<String> collection = new ImportsCollection(this);
		
		String className = getClassName();
		String superclassName = getQualifiedSuperclassName();

		if (superclassName != null && superclassName.length() > 0 &&
				!areFlagsSet(FLAG_QUALIFIED_SUPERCLASS_NAME) && 
				!equalSimpleNames(className, superclassName)) {
			collection.add(superclassName);
		}
		
		List<String> interfaces = getQualifiedInterfaces();
		if (interfaces != null) {
			for (String iface : interfaces) {
				if (!equalSimpleNames(getClassName(), iface)) { 
					collection.add(iface);
				}
			}
		}
		
		List<Constructor> constructors = getConstructors();
		for (Constructor constructor : constructors) {
			List<String> types = constructor.getNonPrimitiveParameterTypes();
			for (String type : types) {
				collection.add(type);
			}
		}
		
		Collection<Method> methods = getUnimplementedMethods();
		for (Method method : methods) {
			collection.addAll(method.getParameterImports());
			collection.addAll(method.getReturnTypeImports());
		}
		
		return collection;
	}

	public String getClassName() {
		return getProperty(CLASS_NAME).trim();
	}

	public String getJavaPackageName() {
		return getProperty(JAVA_PACKAGE).trim();
	}

	public String getQualifiedJavaClassName() {
		return getJavaPackageName() + "." + getClassName(); //$NON-NLS-1$
	}

	public String getSuperclassName() {
		String qualified = getQualifiedSuperclassName();
		if (areFlagsSet(FLAG_QUALIFIED_SUPERCLASS_NAME) || equalSimpleNames(getClassName(), qualified)) {
			return qualified;
		}
		return Signature.getSimpleName(qualified);
	}
	
	public String getQualifiedSuperclassName() {
		return getProperty(SUPERCLASS).trim();
	}
	
	public List<String> getInterfaces() {
		List<String> qualifiedInterfaces = getQualifiedInterfaces();
		List<String> interfaces = new ArrayList<String>(qualifiedInterfaces.size());
		
		for (String qualified : qualifiedInterfaces) {
			if (equalSimpleNames(getClassName(), qualified)) {
				interfaces.add(qualified);
			} else {
				interfaces.add(Signature.getSimpleName(qualified));
			}
		}
		
		return interfaces;
	}

	public List<String> getQualifiedInterfaces() {
		List<String> interfaces = (List<String>) dataModel.getProperty(INTERFACES);
		return (interfaces == null) ? new ArrayList<String>() : interfaces;
	}

	public boolean isPublic() {
		return dataModel.getBooleanProperty(MODIFIER_PUBLIC);
	}

	public boolean isFinal() {
		return dataModel.getBooleanProperty(MODIFIER_FINAL);
	}

	public boolean isAbstract() {
		return dataModel.getBooleanProperty(MODIFIER_ABSTRACT);
	}
	
	public boolean shouldGenSuperclassConstructors() {
		return dataModel.getBooleanProperty(CONSTRUCTOR);
	}
    
    public boolean shouldImplementAbstractMethods(){
		return dataModel.getBooleanProperty(ABSTRACT_METHODS);
	}

    public boolean hasEmptySuperclassConstructor() {
    	List<Constructor> constructors = getConstructors();
    	for (Constructor constructor : constructors) {
    		if (constructor.isParameterless())
    			return true;
    	}
        
    	return false;
	}
	
    public List<Constructor> getConstructors() {
        List<Constructor> constrs = new ArrayList<Constructor>();
        
        String superclass = dataModel.getStringProperty(SUPERCLASS);
        if (superclass != null && superclass.length() > 0) {
            IProject p = (IProject) dataModel.getProperty(PROJECT);
            IJavaProject javaProject = JavaCore.create(p);
            if (javaProject != null) {
                try {
                    IType type = javaProject.findType(superclass);
                    if (type != null) {
	                    if (type.isBinary()) {
	                        IMethod[] methods = type.getMethods();
	                        for (IMethod method : methods) {
	                            if (method.isConstructor()) 
	                                constrs.add(new BinaryConstructor(method));
	                        }
	                    } else {
	                    	ICompilationUnit compilationUnit = type.getCompilationUnit();
	                        TypeDeclaration declarationFromType = getTypeDeclarationFromType(superclass, compilationUnit);
	                        if (declarationFromType != null) {
	                            MethodDeclaration[] methods = declarationFromType.getMethods();
	                            for (MethodDeclaration method : methods) {
	                                if (method.isConstructor()) 
	                                    constrs.add(new SourceConstructor(method));
	                            }
	                        }
	                    }
                    }
                } catch (JavaModelException e) {
                	J2EEPlugin.logError(e);
                }
            }
        }
        
        return constrs;
    }
	
	public Collection<Method> getUnimplementedMethods() {
        Collection<Method> unimplementedMethods = new HashSet<Method>();
        
        if (shouldImplementAbstractMethods()) {
        	IJavaProject javaProject = getJavaProject();
    	    List<String> interfaces = getQualifiedInterfaces();
	        for (String iface : interfaces) {
        		try {
		        	IType type = javaProject.findType(iface);
		        	if (type != null)
	        			getUnimplementedMethod0(type, unimplementedMethods);
        		} catch (JavaModelException e) {
        			J2EEPlugin.logError(e);
    	        }
	        }
        }
        
        return unimplementedMethods;
    }
	
	private void getUnimplementedMethod0(IType type, Collection<Method> unimplementedMethods) throws JavaModelException {
		IJavaProject javaProject = getJavaProject();
		if (type.isBinary()) {
		    IMethod[] methods = type.getMethods();
		    for (IMethod method : methods) {
		    	unimplementedMethods.add(new BinaryMethod(method));
		    }
		    
		    // process super interfaces
		    String[] superInterfaces = type.getSuperInterfaceNames();
			for (String superInterface : superInterfaces) {
				IType superInterfaceType = javaProject.findType(superInterface);
				if (superInterfaceType != null) 
					getUnimplementedMethod0(superInterfaceType, unimplementedMethods);
			}
		} else {
			ICompilationUnit compilationUnit = type.getCompilationUnit();
		    TypeDeclaration declarationFromType = getTypeDeclarationFromType(type.getFullyQualifiedName(), compilationUnit);
		    if (declarationFromType != null) {
		        MethodDeclaration[] methods = declarationFromType.getMethods();
		        for (MethodDeclaration method : methods) {
		        	unimplementedMethods.add(new SourceMethod(method));
		        }
		        // process super interfaces
			    List<Type> superInterfaces = declarationFromType.superInterfaceTypes();
			    for (Type superInterface : superInterfaces) {
			    	ITypeBinding binding = superInterface.resolveBinding();
			    	IType superInterfaceType = javaProject.findType(binding.getQualifiedName());
					if (superInterfaceType != null) 
						getUnimplementedMethod0(superInterfaceType, unimplementedMethods);
			    }
		    }
		    
		   
		}
	}

	protected String getProperty(String propertyName) {
		return dataModel.getStringProperty(propertyName);
	}
	
	protected boolean equalSimpleNames(String name1, String name2) {
		String simpleName1 = Signature.getSimpleName(name1);
		String simpleName2 = Signature.getSimpleName(name2);
		return simpleName1.equals(simpleName2);
	}

    protected IJavaProject getJavaProject() {
    	IProject p = (IProject) dataModel.getProperty(PROJECT);
        return JavaCore.create(p);
    }
    
    private TypeDeclaration getTypeDeclarationFromType(String typeName, ICompilationUnit unit) {
        CompilationUnit cu = (CompilationUnit) parse(unit);
        Iterator iterator = cu.types().iterator();
        while (iterator.hasNext()) {
        	Object obj = iterator.next();
        	if (obj instanceof TypeDeclaration) {
	            TypeDeclaration declaration = (TypeDeclaration) obj;
	            ITypeBinding tb = declaration.resolveBinding();
	            if (tb != null) {
	                String declarationName = tb.getQualifiedName();
	                if (typeName.equals(declarationName)) {
	                    return declaration;
	                }
	            }
        	}
        }

        return null;
    }
    
    private ASTNode parse(ICompilationUnit unit) {
        ASTParser parser = ASTParser.newParser(AST.JLS3);
        parser.setKind(ASTParser.K_COMPILATION_UNIT);
        parser.setSource(unit);
        parser.setResolveBindings(true);
        parser.setStatementsRecovery(true);
        return parser.createAST(null);
    }
    
}
