/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.jsdt.core.tests.model;

import java.util.Comparator;
import java.util.List;

import org.eclipse.wst.jsdt.core.Flags;
import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.wst.jsdt.core.dom.ArrayType;
import org.eclipse.wst.jsdt.core.dom.BodyDeclaration;
import org.eclipse.wst.jsdt.core.dom.FieldDeclaration;
import org.eclipse.wst.jsdt.core.dom.FunctionDeclaration;
import org.eclipse.wst.jsdt.core.dom.Initializer;
import org.eclipse.wst.jsdt.core.dom.Name;
import org.eclipse.wst.jsdt.core.dom.PrimitiveType;
import org.eclipse.wst.jsdt.core.dom.QualifiedName;
import org.eclipse.wst.jsdt.core.dom.SimpleName;
import org.eclipse.wst.jsdt.core.dom.SimpleType;
import org.eclipse.wst.jsdt.core.dom.SingleVariableDeclaration;
import org.eclipse.wst.jsdt.core.dom.Type;
import org.eclipse.wst.jsdt.core.dom.VariableDeclarationFragment;
import org.eclipse.wst.jsdt.core.util.JavaScriptUnitSorter;

import com.ibm.icu.text.Collator;

/**
 * The class <code>DefaultJavaElementComparator</code> is a standard
 * implementation of a comparator.
 * <p>
 * <ul>
 * <li>static fields, arranged alphabetically by name and access modifier
 * (public, protected, private, default)</li>
 * <li>static initializers in order of appearance</li>
 * <li>instance fields, arranged alphabetically by name and access modifier
 * (public, protected, private, default)</li>
 * <li>instance initializers in order of appearance</li>
 * <li>type declarations, arranged alphabetically by name and access modifier
 * (public, protected, private, default)</li>
 * <li>constructors, arranged by parameter order and access modifier
 * (public, protected, private, default)</li>
 * <li>methods, arranged by alphabetically by name and parameter order and 
 * access modifier (public, protected, private, default)</li>
 * </p>
 */
class DefaultJavaElementComparator implements Comparator {

	private static final int STATIC_TYPE_CATEGORY = 0;
	private static final int STATIC_FIELD_CATEGORY = 1;
	private static final int STATIC_INITIALIZER_CATEGORY = 2;
	private static final int STATIC_METHOD_CATEGORY = 3;
	private static final int TYPE_CATEGORY = 4;
	private static final int FIELD_CATEGORY = 5;
	private static final int INITIALIZER_CATEGORY = 6;
	private static final int CONSTRUCTOR_CATEGORY = 7;
	private static final int METHOD_CATEGORY = 8;
	
	private Collator collator;
	
	private int[] categories;
	
	/**
	 * Creates an instance that sorts the various categories of body
	 * declarations in the following order:
	 * <ol>
	 * <li>static types</li>
	 * <li>static fields </li>
	 * <li>static initializers</li>
	 * <li>non-static fields</li>
	 * <li>instance initializers</li>
	 * <li>types</li>
	 * <li>static methods</li>
	 * <li>constructors</li>
	 * <li>non-static methods</li>
	 * </ol>
	 */
	public DefaultJavaElementComparator() {
		// initialize default categories
		this.categories = new int[] {
			1, // static type
			2, // static field
			3, // static initializer
			7, // static method
			6, // type
			4, // field
			5, // initializer
			8, // constructor
			9  // method
		};
		this.collator = Collator.getInstance();
	}

	/**
	 * Creates an instance that arranges the various categories of body
	 * declarations.
	 * This constructor is used to specify customized values for the different categories.
	 * They are a convinient way to distinguish AST nodes. 
	 * The lower a value is, the higher the node will appear in the sorted
	 * compilation unit.
	 * <p>
	 * There are nine categories with theirs default values:
	 * <ol>
	 * <li>static types (1)</li>
	 * <li>static fields (2)</li>
	 * <li>static initializers (3)</li>
	 * <li>fields (4) </li>
	 * <li>initializers (5)</li>
	 * <li>types (6)</li>
	 * <li>static methods (7)</li>
	 * <li>constructors (8)</li>
	 * <li>methods (9)</li>
	 * </ol>
	 * </p>
	 * 
	 * @param staticTypeCategory the given value for the static type category
	 * @param staticFieldCategory the given value for the static field category
	 * @param staticInitializerCategory the given value for the static initializer category
	 * @param staticMethodCategory the given value for static the method category
	 * @param typeCategory the given value for the type category
	 * @param fieldCategory the given value for field category
	 * @param initializerCategory the given value for initializer category
	 * @param constructorCategory the given value for constructor category
	 * @param methodCategory the given value for method category
	 */
	public DefaultJavaElementComparator(
		int staticTypeCategory,
		int staticFieldCategory,
		int staticInitializerCategory,
		int staticMethodCategory,
		int typeCategory,
		int fieldCategory,
		int initializerCategory,
		int constructorCategory,
		int methodCategory) {
			this.categories = new int[] {
				staticTypeCategory,
				staticFieldCategory,
				staticInitializerCategory,
				staticMethodCategory,
				typeCategory,
				fieldCategory,
				initializerCategory,
				constructorCategory,
				methodCategory
			};
		this.collator = Collator.getInstance();
	}

	/**
	 * This method is used to retrieve the category for a body declaration node according to the 
	 * preferences passed at the creation of the comparator.
	 * 
	 * @param node the given node
	 * @return the category corresponding to the given node
	 * 
	 * @since 2.1
	 */
	private int getCategory(BodyDeclaration node) {
		switch(node.getNodeType()) {
			case ASTNode.FUNCTION_DECLARATION :
				FunctionDeclaration methodDeclaration = (FunctionDeclaration) node;
				if (methodDeclaration.isConstructor()) {
					return this.categories[CONSTRUCTOR_CATEGORY];
				}
				if (Flags.isStatic(methodDeclaration.getModifiers())) {
					return this.categories[STATIC_METHOD_CATEGORY];
				}
				return this.categories[METHOD_CATEGORY];
			case ASTNode.FIELD_DECLARATION :
				FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
				if (Flags.isStatic(fieldDeclaration.getModifiers())) {
					return this.categories[STATIC_FIELD_CATEGORY];
				}
				return this.categories[FIELD_CATEGORY];
			case ASTNode.TYPE_DECLARATION :
				AbstractTypeDeclaration abstractTypeDeclaration = (AbstractTypeDeclaration) node;
				if (Flags.isStatic(abstractTypeDeclaration.getModifiers())) {
					return this.categories[STATIC_TYPE_CATEGORY];
				}
				return this.categories[TYPE_CATEGORY];
			case ASTNode.INITIALIZER :
				Initializer initializer = (Initializer) node;
				if (Flags.isStatic(initializer.getModifiers())) {
					return this.categories[STATIC_INITIALIZER_CATEGORY];
				}
				return this.categories[INITIALIZER_CATEGORY];
		}
		return 0;
	}

	/**
	 * The <code>DefaultJavaElementComparator</code> implementation of this
	 * <code>java.util.Comparator</code> method can only be used to compare
	 * instances of <code>org.eclipse.wst.jsdt.core.dom.BodyDeclaration</code>.
	 * <p>
	 * The categories of each body declaration are compared. If they are
	 * in different categories, they are ordered based on their category.
	 * Body declarations within the same category are ordered by signature
	 * string. Body declarations with the same signature string are ordered
	 * by their original relative positions.
	 * </p>
	 */
	public int compare(Object o1, Object o2) {
		if (!(o1 instanceof BodyDeclaration) && !(o2 instanceof BodyDeclaration)) {
			throw new ClassCastException();
		}
		BodyDeclaration node1 = (BodyDeclaration) o1;
		BodyDeclaration node2 = (BodyDeclaration) o2;
		int category1 = getCategory(node1);
		int category2 = getCategory(node2);
		
		if (category1 != category2) {
			return category1 - category2;
		}
		if (o1 == o2) {
			return 0;
		}
		String node1Signature = buildSignature(node1);
		String node2Signature = buildSignature(node2);
		if (node1Signature.length() != 0 && node2Signature.length() != 0) {
			int compare = this.collator.compare(node1Signature, node2Signature);
			if (compare != 0) {
				return compare;
			}
		}
		int sourceStart1 = ((Integer) node1.getProperty(JavaScriptUnitSorter.RELATIVE_ORDER)).intValue();
		int sourceStart2 = ((Integer) node2.getProperty(JavaScriptUnitSorter.RELATIVE_ORDER)).intValue();
		return sourceStart1 - sourceStart2;
	}

	private String buildSignature(BodyDeclaration node) {
		switch(node.getNodeType()) {
			case ASTNode.FUNCTION_DECLARATION :
				FunctionDeclaration methodDeclaration = (FunctionDeclaration) node;
				StringBuffer buffer = new StringBuffer();
				buffer.append(methodDeclaration.getName().getIdentifier());
				final List parameters = methodDeclaration.parameters();
				int length1 = parameters.size();
				for (int i = 0; i < length1; i++) {
					SingleVariableDeclaration parameter = (SingleVariableDeclaration) parameters.get(i);
					buffer.append(parameter.getName().getIdentifier());
					Type type = parameter.getType();
					buffer.append(buildSignature(type));
				}
				return String.valueOf(buffer);
			case ASTNode.FIELD_DECLARATION :
				FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
				return ((VariableDeclarationFragment) fieldDeclaration.fragments().get(0)).getName().getIdentifier();
			case ASTNode.INITIALIZER :
				return ((Integer) node.getProperty(JavaScriptUnitSorter.RELATIVE_ORDER)).toString();
			case ASTNode.TYPE_DECLARATION :
				AbstractTypeDeclaration abstractTypeDeclaration = (AbstractTypeDeclaration) node;
				return abstractTypeDeclaration.getName().getIdentifier();
		}
		return null;
	}

	private String buildSignature(Type type) {
		switch(type.getNodeType()) {
			case ASTNode.PRIMITIVE_TYPE :
				PrimitiveType.Code code = ((PrimitiveType) type).getPrimitiveTypeCode();
				return code.toString();
			case ASTNode.ARRAY_TYPE :
				ArrayType arrayType = (ArrayType) type;
				StringBuffer buffer = new StringBuffer();
				buffer.append(buildSignature(arrayType.getElementType()));
				int dimensions = arrayType.getDimensions();
				for (int j = 0; j < dimensions; j++) {
					buffer.append("[]"); //$NON-NLS-1$
				}
				return buffer.toString();
			case ASTNode.SIMPLE_TYPE :
				SimpleType simpleType = (SimpleType) type;
				return buildSignature(simpleType.getName());
		}
		return null; // should never happen
	}
	
	private String buildSignature(Name name) {
		if (name.isSimpleName()) {
			return ((SimpleName) name).getIdentifier();
		}
		QualifiedName qualifiedName = (QualifiedName) name;
		return buildSignature(qualifiedName.getQualifier()) + "." + buildSignature(qualifiedName.getName()); //$NON-NLS-1$
	}
}
