/*******************************************************************************
 * 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 { 
	
	public static final String ATT_NAME = "name"; //$NON-NLS-1$
	public static final String ATT_DESCRIPTION = "description"; //$NON-NLS-1$
	
	/**
	 * 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);
    }
    
}
