/*******************************************************************************
 * Copyright (c) 2013 Oracle. All rights reserved.
 * 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/.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/

package org.eclipse.jpt.jpa.annotate.util;

import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jpt.common.utility.internal.ClassNameTools;
import org.eclipse.jpt.common.utility.internal.NameTools;
import org.eclipse.jpt.common.utility.internal.StringTools;

public class AnnotateMappingUtil
{
	public static final String[] REPEATING_TYPES = new String[]
    {
		java.util.Collection.class.getName(),
		java.util.Enumeration.class.getName(),
		java.util.Iterator.class.getName(),
		java.util.Map.class.getName()
    };	
	
    /** java primitive types */
    public static String[] PRIMITIVE_TYPES = new String[] { "int",      //$NON-NLS-1$
                                                            "double",   //$NON-NLS-1$
                                                            "long",     //$NON-NLS-1$
                                                            "short",    //$NON-NLS-1$
                                                            "byte",     //$NON-NLS-1$
                                                            "float",    //$NON-NLS-1$
                                                            "boolean",  //$NON-NLS-1$
                                                            "char",     //$NON-NLS-1$
                                                            "void" };   //$NON-NLS-1$
    public static String[] PRIMITIVE_WRAPPERS = new String[] {Integer.class.getName(),
        Double.class.getName(),
        Long.class.getName(),
        Short.class.getName(),
        Byte.class.getName(),
        Float.class.getName(),
        Boolean.class.getName(),
        Character.class.getName()};
	
    public final static String GET_PREFIX = "get";  //$NON-NLS-1$
    public final static String IS_PREFIX  = "is";   //$NON-NLS-1$
    public final static String BOOLEAN = "boolean"; //$NON-NLS-1$
    
    public static boolean isRepeatingType(String type, IProject project) throws JavaModelException
	{
		if (isArrayType(type))
			return true;
		String strippedType = stripTypeParameters(type);
		for (String repeatingType : REPEATING_TYPES)
		{
			if (strippedType.equals(repeatingType) ||
					isAssignableFrom(strippedType, repeatingType, project))
				return true;
		}
		return false;
	}
	
	
	/**
	 * Returns the properties in refType of the same type entityClass.
	 * 
	 */
	public static Set<String> getMappedByList(String entityClass, IType refType, boolean isManyToMany)
		throws JavaModelException
	{
		Set<String> propNames = new java.util.HashSet<String>();
		IField[] fields = refType.getFields();
		for (IField field : fields)
		{
			// filter out static/inherited fields
			if (Flags.isStatic(field.getFlags()) || Flags.isSuper(field.getFlags()))
				continue;
			
			String fieldType = getFieldType(field, refType);
			String dt = null;
			if (fieldType != null)
			{
				if (isManyToMany) 
				{
					dt = getGenericsComponentTypeName(fieldType);
					if (dt != null)
						dt = resolveType(dt, refType);
				} else 
				{
					dt = fieldType;
				}
			}
			if (dt != null && dt.equals(entityClass)) 
			{
				propNames.add(field.getElementName());
			}
		}
		return propNames;
	}

	public static String getGenericsComponentTypeName(String s) 
	{
		//s is in the form T<x, y>
		int i1 = s.indexOf('<');
		if (i1 < 0) {
			return null;
		}
		int i2 = s.indexOf('>', i1);
		if (i2 < 0) {
			return null;
		}
		String typeName = s.substring(i1+1, i2);
		//don't bother with the Map case for now
		if (typeName.indexOf(',') >= 0) {
			return null;
		}
		
		return typeName;
	}
	
	/**
	 * returns the fully qualified type for an IField
	 * @param field
	 * @param containingType
	 * @return
	 * @throws JavaModelException
	 */
	public static String getFieldType(IField field, IType containingType) throws JavaModelException
	{
		String shortType = field.getTypeSignature();
		shortType = Signature.toString(shortType);
		if (ClassNameTools.isPrimitive(shortType))
			return shortType;
		String type = resolveType(shortType, containingType);
		return type;
	}
	
	public static boolean isNumeric(String type)
	{
		return (type.equals(Integer.class.getName()) || type.equals(Integer.TYPE.getName())
				|| type.equals(Float.class.getName()) || type.equals(Float.TYPE.getName())
				|| type.equals(Double.class.getName()) || type.equals(Double.TYPE.getName())
				|| type.equals(Short.class.getName()) || type.equals(Short.TYPE.getName())
				|| type.equals(Long.class.getName()) || type.equals(Long.TYPE.getName())
				|| type.equals(Byte.class.getName()) || type.equals(Byte.TYPE.getName()) 
				|| type.equals(Number.class.getName())
				|| type.equals(BigDecimal.class.getName()));	
	}
	
	public static boolean isString(String type)
	{
		return (type.equals(String.class.getName()));
	}
		
	public static boolean isDate(String type, IProject proj) throws JavaModelException
	{
		return isAssignableFrom(type, Date.class.getName(), proj) ||
			isAssignableFrom(type, Calendar.class.getName(), proj);
	}
	
	public static boolean isTime(String type)
	{
		return (type.equals(Time.class.getName()) || type.equals(Timestamp.class.getName()));
	}
	
	public static boolean isBoolean(String type)
	{
		return (type.equals(Boolean.class.getName()) || type.equals(Boolean.TYPE.getName()));
	}
	
    /**
     * Checks if this type is an array type ie type has [] at the end.
     */
    public static boolean isArrayType( String type )
    {
        return type.endsWith( "[]" ); //$NON-NLS-1$
    }

    public static boolean hasMatchingTypeParameterBraces( String type )
    {
        assert type != null : "Type was null."; //$NON-NLS-1$
        char[] chars = type.toCharArray();
        int openCount = 0;
        int closeCount = 0;
        
        for ( int i = 0; i < chars.length; ++i )
        {
            if ( chars[i] == '<' )
                ++openCount;
            
            if ( chars[i] == '>' )
                ++closeCount;
            
            if ( closeCount > openCount )
                return false;
        }
        
        return openCount == closeCount; 
    }
    
    /**
     * returns true if the array brackets on the string type are properly matched
     * false otherwise
     */
    public static boolean hasMatchingArrayBrackets( String type )
    {
        int firstBracket = type.indexOf( "[" ); //$NON-NLS-1$
        int nextBracket  = type.indexOf( "]" ); //$NON-NLS-1$
        
        // if no brackets at all, return true
        if ( firstBracket == -1 && nextBracket == -1 )
        {
            return true;
        }
        
        String tempType = type;
        
        while( tempType.length() > 0 )
        {
            nextBracket = tempType.indexOf( "]" ); //$NON-NLS-1$
            if ( nextBracket < firstBracket || 
                    firstBracket == -1 ||
                    nextBracket != firstBracket + 1 )
            {
                return false;
            }
            tempType = tempType.substring( nextBracket + 1 );
            firstBracket = tempType.indexOf( "[" ); //$NON-NLS-1$
        }
        return true;
    }
    
    
    /**
     * Strips type parameter information from a type name, for example "java.util.List<java.lang.String>"
     * would become "java.util.List". Stripping "<>" would become "".  If the "<" don't match, then
     * the provided type name is returned as-is, for example "List<<>" would be returned as "List<<>".
     * This will not return null.
     */
    public static String stripTypeParameters( String typeName )
    {
        assert typeName != null : "Type name was null."; //$NON-NLS-1$
        
        if ( hasMatchingTypeParameterBraces( typeName ) )
        {
	        int index = typeName.indexOf( '<' );
	        
	        if ( index > -1 )
	            typeName = typeName.substring( 0, index ).trim();
        }
	        
        assert typeName != null : "Returning null type.";  //$NON-NLS-1$
        return typeName;
    }
    
    /**
     * Strips any array dimensions off of the provided type name.
     * For example, stripping "Foo[]" will return "Foo".  If the brackets
     * are not matched, the type name will be returned unchanged.  For example,
     * stripping "Foo]" will return "Foo]", and stripping "Foo[][" will 
     * return "Foo[][".  Stripping "[]" will return "".  Null is not returned.
     */
    public static String stripArrayDimensions( String typeName )
    {
        assert typeName != null : "Type name was null.";  //$NON-NLS-1$
        
        if ( hasMatchingArrayBrackets( typeName ) )
        {
	        typeName = stripTypeParameters( typeName ); // Deal with things like Collection<String[]>
	        int index = typeName.indexOf( '[' );

	        if( index > -1 )
	            typeName = typeName.substring( 0, index ).trim();
        }
        
        assert typeName != null : "Returning null type.";  //$NON-NLS-1$
        return typeName;
    }
    
    
    /**
     * Retrieves an IType for a given Java project or any project it references.
     * Anonymous types cannot be retrieved with this method.  
     * @param fullyQualifiedType The fully qualified name of the type - for example "java.lang.String".  
     *        This doesn't work for primitive or array types, such as "int" or "Foo[]".
     * @param project The project that is in scope.
     */
    public static IType getType( String fullyQualifiedType, IProject project ) throws JavaModelException
    {
        assert fullyQualifiedType != null : "Fully qualified type should not be null."; //$NON-NLS-1$
        
        // the JDT returns a non-null anonymous class IType 
        // for empty string and package names that end with a dot
        // if the type starts with a dot, the JDT helpfully removes it 
        // and returns the type referenced without the dot
        // short circuit here for perf and so validation results make sense
        // e.g. if the valid type is "Thing", then ".Thing" and "Thing." should not be valid
        if ( fullyQualifiedType.trim().length() == 0 
                || fullyQualifiedType.startsWith(".") //$NON-NLS-1$
                        || fullyQualifiedType.endsWith(".")) //$NON-NLS-1$
            return null;
        
        int ltIndex = fullyQualifiedType.indexOf( '<' );
        int gtIndex = fullyQualifiedType.lastIndexOf( '>' );
        if ( ltIndex != -1 && gtIndex != -1 && gtIndex > ltIndex )
            assert false : 
                "Type should have type parameter info stripped before calling this method: " + fullyQualifiedType; //$NON-NLS-1$
        assert !isArrayType( fullyQualifiedType ) : "Type should have array brackets stripped before calling: " + //$NON-NLS-1$
            fullyQualifiedType;
        assert project != null : "Project should not be null."; //$NON-NLS-1$

        // if the project is not accessible, this will cause a JavaModelException below
        if ( !project.isAccessible() )
        {
            return null;
        }
        
        IJavaProject javaProject = JavaCore.create( project );
        
        if (( javaProject == null ) || ( !javaProject.exists() ))
        {
            return null;
        }

        IType type = null;
        type = javaProject.findType( fullyQualifiedType );
        if ( type != null && ( !type.exists() || type.isAnonymous() ) )
        {
        	type = null;
        }
        return type;
    }

    /**
     * Determines if the class or interface represented by the subtype name is either the same as, or is a superclass
     * or superinterface of, the class or interface represented by the specified supertype name. It returns true if
     * so; otherwise it returns false.  This method will not block and wait if the required compiler information is not
     * instantly available - in this case it will return false right away.  Callers should be aware that false can
     * sometimes mean that "we could neither confirm nor deny that the type is assignable from the super type".  Callers
     * should handle this by calling this method as often as needed and not caching the result.  Type parameter
     * information should be removed before calling this method (see {@link #stripTypeParameters(String)} for
     * this purpose).
     * @param fullyQualifiedSubTypeName The subtype name.
     * @param fullyQualifiedSuperTypeName The supertype name.
     * @param project The relevant project.  If null is passed for this parameter, then it attempts to
     *                determine the active Java project based on the current editor.  If no Java project can be
     *                determined, then this method will definitley return false.
     */
    public static boolean isAssignableFrom( String fullyQualifiedSubTypeName, String fullyQualifiedSuperTypeName,
                                            IProject project ) throws JavaModelException
    {
        assert fullyQualifiedSubTypeName != null : "Sub type name was null."; //$NON-NLS-1$
        assert fullyQualifiedSuperTypeName != null : "Super type name was null."; //$NON-NLS-1$
        assert fullyQualifiedSubTypeName.indexOf( '<' ) == -1 : 
            "Subtype should have type parameter info stripped before calling this method: " +  //$NON-NLS-1$
            fullyQualifiedSubTypeName;
        assert fullyQualifiedSuperTypeName.indexOf( '<' ) == -1 : 
            "Supertype should have type parameter info stripped before calling this method: " +  //$NON-NLS-1$
            fullyQualifiedSuperTypeName;
        boolean assignableFrom = false;
        
        if ( project != null )
        {
            IType subType = getType( fullyQualifiedSubTypeName, project );
            IType superType = getType( fullyQualifiedSuperTypeName, project );
            
            if ( subType != null && superType != null )
            {
                ITypeHierarchy th = subType.newSupertypeHierarchy( null );
                assert th != null : "Type hierarchy was null."; //$NON-NLS-1$
                assignableFrom = th.contains( superType );
            }
        }
        
        return assignableFrom;
    }
 
     /**
      * Resolves a type name against an IType to get a fully qualified type name. If
      * it cannot be resolved for some reason (eg. the type is ambiguous), this returns null.
      */
     public static String resolveType( String typeName, IType type ) throws JavaModelException
     {
         assert typeName != null : "Type name was null."; //$NON-NLS-1$
         assert type != null : "Type was null."; //$NON-NLS-1$
         int bracketIndex = typeName.indexOf( '[' );
         int typeParamIndex = typeName.indexOf( '<' );
         int suffixIndex = -1;
         String typeSuffix = null;
         
         if ( bracketIndex > -1 && typeParamIndex > -1 )
             suffixIndex = bracketIndex <= typeParamIndex ? bracketIndex : typeParamIndex;
         else if ( bracketIndex > -1 )
             suffixIndex = bracketIndex;
         else if ( typeParamIndex > -1 )
             suffixIndex = typeParamIndex;
         
         if ( suffixIndex > -1 )
         {
             typeSuffix = typeName.substring( suffixIndex );
             typeName = typeName.substring( 0, suffixIndex ).trim();
         }
         
         String value = null;
         String[][] typeMatches = type.resolveType( typeName );
         
         // If typeMatches.length > 1 then the type was ambiguous.  We return null in that case.
         if ( typeMatches != null && typeMatches.length == 1 )
         {
             value = ( typeMatches[0][0].length() == 0 ?  typeMatches[0][1] :
                 typeMatches[0][0] + "." + typeMatches[0][1] ); //$NON-NLS-1$
         }
         
         if ( value == null && type.isBinary() )
         {
             // For some reason, resolving types against binary types doesn't always 
             // (ever?) work.  If the type we're trying to resolve it against is binary,
             // try to resolve against the project instead (and since there should only
             // be one reachable type with a given fully qualified name on the project 
             // classpath anyway, this should be legit).
             IProject project = type.getJavaProject().getProject();
             assert project != null : "Project was null.";  //$NON-NLS-1$
             IType resolvedType = getType( typeName, project );
             
             if ( resolvedType != null )
                 value = resolvedType.getFullyQualifiedName( '.' );
         }
         
         if ( value != null && typeSuffix != null )
             value += typeSuffix;
             
         return value;
     }
 
 
     /**
      * Strips out package information and returns the java class name
      * If the class uses &lt;&gt;, then keep that in.
      * Examples: <pre>
      *  getClassName("MyClass") = "MyClass"
      *  getClassName("java.util.ArrayList") = "ArrayList"
      *  getClassName("java.util.String[]") = "String[]"
      *  getClassName("java.util.ArrayList&lt;java.lang.String&gt;") = "ArrayList&lt;String&gt;"
      *  getClassName("java.util.ArrayList&lt;java.lang.ArrayList&lt;String&gt;&gt;") = ArrayList&lt;ArrayList&lt;String&gt;&gt;
      *  getClassName("java.util.ArrayList&lt;java.lang.String[]&gt;[]") = ArrayList&lt;String[]&gt;[]
      * </pre>
      * @param fullClassName the fully qualified class name
      * @return the name of the class
      */
     public static String getClassName( String fullClassName )
     {
         if ( fullClassName == null )
         {
             return null;
         }
         else
         {
             int endBracket = fullClassName.lastIndexOf('>');  //$NON-NLS-1$
             if (endBracket >= 0)
             {
                 int beginBracket = fullClassName.indexOf('<');  //$NON-NLS-1$
                 assert beginBracket >= 0 : "no matching '<' for '>' in " + fullClassName;  //$NON-NLS-1$
                 assert beginBracket < endBracket : "bad class syntax in " + fullClassName; //$NON-NLS-1$
                 return (getClassName(fullClassName.substring(0, beginBracket)) + "<" + //$NON-NLS-1$
                         getClassName(fullClassName.substring(beginBracket + 1, endBracket)) + ">" +  //$NON-NLS-1$
                         fullClassName.substring(endBracket + 1));
             }
             else
             {
                 int dotpos = fullClassName.lastIndexOf( '.' );
                 return ( dotpos < 0 )? fullClassName : fullClassName.substring( dotpos + 1 );
             }
         }
     }

     /******************************************************************************
      * Determines is two objects are equal, accounting for one or both
      * objects being null or the two objects being array types.
      * @param o1  The first object to compare.
      * @param o2  The second object to compare.
      * @return  True if the two objects are equal.
      ******************************************************************************/
     public static final boolean areEqual( Object o1, Object o2 )
     {
         boolean objectsAreEqual = false;
         if( o1 == o2 )
         {
             objectsAreEqual = true;
         }
         else if ( o1 != null && o2 != null )
         {
             if ( o1.getClass().isArray() && o2.getClass().isArray() )
             {
                 objectsAreEqual = Arrays.equals(
                     ( Object[] ) o1, ( Object[] ) o2 );
             }
             else
             {
                 objectsAreEqual = o1.equals( o2 );
             }
         }

         return objectsAreEqual;
     }
     
     public static String dbNameToJavaName(String dbName)
     {
		String result = dbName;
		if (StringTools.isUppercase(result) || StringTools.isLowercase(result)) {
			// leave mixed case identifiers alone?
			result = StringTools.convertAllCapsToCamelCase(result, false);
		}
		result = NameTools.convertToJavaIdentifier(result);
		return result;    	 
     }
     
 	/**
 	 * Utility methods used to convert DB object names to  
 	 * appropriate Java type and field name 
 	 */
 	public static String pluralise(String name) {
 		String result = name;
 		if (name.length() == 1) {
 			result += 's';
 		} else if (!seemsPluralised(name)) {
 			String lower = name.toLowerCase();
 			if (!lower.endsWith("data")) { //orderData --> orderDatas is dumb
 				char secondLast = lower.charAt(name.length() - 2);
 				if (!isVowel(secondLast) && lower.endsWith("y")) {
 					// city, body etc --> cities, bodies
 					result = name.substring(0, name.length() - 1) + "ies";
 				} else if (lower.endsWith("ch") || lower.endsWith("s")) {
 					// switch --> switches  or bus --> buses
 					result = name + "es";
 				} else {
 					result = name + "s";
 				}
 			}
 		}
 		return result;
 	}

 	public static String singularise(String name) {
 		String result = name;
 		if (seemsPluralised(name)) {
 			String lower = name.toLowerCase();
 			if (lower.endsWith("ies")) {
 				// cities --> city
 				result = name.substring(0, name.length() - 3) + "y";
 			} else if (lower.endsWith("ches") || lower.endsWith("ses")) {
 				// switches --> switch or buses --> bus
 				result = name.substring(0, name.length() - 2);
 			} else if (lower.endsWith("s")) {
 				// customers --> customer
 				result = name.substring(0, name.length() - 1);
 			}
 		}
 		return result;
 	}
 	private final static boolean isVowel(char c) {
 		boolean vowel = false;
 		vowel |= c == 'a';
 		vowel |= c == 'e';
 		vowel |= c == 'i';
 		vowel |= c == 'o';
 		vowel |= c == 'u';
 		vowel |= c == 'y';
 		return vowel;
 	}
 	private static boolean seemsPluralised(String name) {
 		name = name.toLowerCase();
 		boolean pluralised = false;
 		pluralised |= name.endsWith("es");
 		pluralised |= name.endsWith("s");
 		pluralised &= !(name.endsWith("ss") || name.endsWith("us"));
 		return pluralised;
 	}
 	
}
