/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     Alex Blewitt - alex_blewitt@yahoo.com https://bugs.eclipse.org/bugs/show_bug.cgi?id=171066
 *******************************************************************************/

package org.aspectj.org.eclipse.jdt.core.util;

import java.util.Comparator;

import org.eclipse.core.runtime.IProgressMonitor;
import org.aspectj.org.eclipse.jdt.core.ICompilationUnit;
import org.aspectj.org.eclipse.jdt.core.IJavaElement;
import org.aspectj.org.eclipse.jdt.core.JavaModelException;
import org.aspectj.org.eclipse.jdt.core.dom.AST;
import org.aspectj.org.eclipse.jdt.core.dom.CompilationUnit;
import org.aspectj.org.eclipse.jdt.internal.core.SortElementsOperation;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;

/**
 * Operation for sorting members within a compilation unit.
 * <p>
 * This class provides all functionality via static members.
 * </p>
 *
 * @since 2.1
 * @noinstantiate This class is not intended to be instantiated by clients.
 */
@SuppressWarnings("rawtypes")
public final class CompilationUnitSorter {

 	/**
 	 * Private constructor to prevent instantiation.
 	 */
	private CompilationUnitSorter() {
		// Not instantiable
	}

    /**
     * @deprecated marking deprecated as it is using deprecated code
     */
    private static void checkASTLevel(int level) {
        switch (level) {
        case AST.JLS2 :
        case AST.JLS3 :
        case AST.JLS4 :
        case AST.JLS8 :
        case AST.JLS9 :
        case AST.JLS10 :
            break;
        default :
            throw new IllegalArgumentException();
        }
    }

	/**
	 * Name of auxillary property whose value can be used to determine the
	 * original relative order of two body declarations. This allows a
	 * comparator to preserve the relative positions of certain kinds of
	 * body declarations when required.
	 * <p>
	 * All body declarations passed to the comparator's <code>compare</code>
	 * method by <code>CompilationUnitSorter.sort</code> carry an
	 * Integer-valued property. The body declaration with the lower value
	 * comes before the one with the higher value. The exact numeric value
	 * of these properties is unspecified.
	 * </p>
	 * <p>
	 * Example usage:
	 * <pre>
	 * BodyDeclaration b1 = (BodyDeclaration) object1;
	 * BodyDeclaration b2 = (BodyDeclaration) object2;
	 * Integer i1 = (Integer) b1.getProperty(RELATIVE_ORDER);
	 * Integer i2 = (Integer) b2.getProperty(RELATIVE_ORDER);
	 * return i1.intValue() - i2.intValue(); // preserve original order
	 * </pre>
	 * </p>
	 *
	 * @see #sort(ICompilationUnit, int[], Comparator, int, IProgressMonitor)
	 * @see org.aspectj.org.eclipse.jdt.core.dom.BodyDeclaration
	 */
	public static final String RELATIVE_ORDER = "relativeOrder"; //$NON-NLS-1$

	/**
	 * Reorders the declarations in the given compilation unit according to
     * JLS2 rules. The caller is
	 * responsible for arranging in advance that the given compilation unit is
	 * a working copy, and for saving the changes afterwards.
	 * <p>
	 * <b>Note:</b> Reordering the members within a type declaration might be
	 * more than a cosmetic change and could have potentially serious
	 * repercussions. Firstly, the order in which the fields of a type are
	 * initialized is significant in the Java language; reordering fields
	 * and initializers may result in compilation errors or change the execution
	 * behavior of the code. Secondly, reordering a class's members may affect
	 * how its instances are serialized. This operation should therefore be used
	 * with caution and due concern for potential negative side effects.
	 * </p>
	 * <p>
	 * The optional <code>positions</code> array contains a non-decreasing
	 * ordered list of character-based source positions within the compilation
	 * unit's source code string. Upon return from this method, the positions in
	 * the array reflect the corresponding new locations in the modified source
	 * code string. Note that this operation modifies the given array in place.
	 * </p>
	 * <p>
	 * The <code>compare</code> method of the given comparator is passed pairs
	 * of JLS2 AST body declarations (subclasses of <code>BodyDeclaration</code>)
	 * representing body declarations at the same level. The comparator is
	 * called on body declarations of nested classes, including anonymous and
	 * local classes, but always at the same level. Clients need to provide
	 * a comparator implementation (there is no standard comparator). The
	 * <code>RELATIVE_ORDER</code> property attached to these AST nodes afforts
	 * the comparator a way to preserve the original relative order.
	 * </p>
	 * <p>
	 * The body declarations passed as parameters to the comparator
	 * always carry at least the following minimal signature information:
	 * <br>
	 * <table border="1" width="80%" cellpadding="5">
	 *	  <tr>
	 *	    <td width="20%"><code>TypeDeclaration</code></td>
	 *	    <td width="50%"><code>modifiers, isInterface, name, superclass,
	 *	      superInterfaces<br>
     *		  RELATIVE_ORDER property</code></td>
	 *	  </tr>
	 *	  <tr>
	 *	    <td width="20%"><code>FieldDeclaration</code></td>
	 *	    <td width="50%"><code>modifiers, type, fragments
	 *        (VariableDeclarationFragments
	 *	      with name only)<br>
     *		  RELATIVE_ORDER property</code></td>
	 *	  </tr>
	 *	  <tr>
	 *	    <td width="20%"><code>MethodDeclaration</code></td>
	 *	    <td width="50%"><code>modifiers, isConstructor, returnType, name,
	 *		  parameters
	 *	      (SingleVariableDeclarations with name and type only),
	 *		  thrownExceptions<br>
     *		  RELATIVE_ORDER property</code></td>
	 *	  </tr>
	 *	  <tr>
	 *	    <td width="20%"><code>Initializer</code></td>
	 *	    <td width="50%"><code>modifiers<br>
     *		  RELATIVE_ORDER property</code></td>
	 *	  </tr>
	 * </table>
	 * Clients should not rely on the AST nodes being properly parented or on
	 * having source range information. (Future releases may provide options
	 * for requesting additional information like source positions, full ASTs,
	 * non-recursive sorting, etc.)
	 * </p>
	 *
	 * @param compilationUnit the given compilation unit, which must be a
	 * working copy
	 * @param positions an array of source positions to map, or
	 * <code>null</code> if none. If supplied, the positions must
	 * character-based source positions within the original source code for
	 * the given compilation unit, arranged in non-decreasing order.
	 * The array is updated in place when this method returns to reflect the
	 * corresponding source positions in the permuted source code string
	 * (but not necessarily any longer in non-decreasing order).
	 * @param comparator the comparator capable of ordering
	 *   <code>BodyDeclaration</code>s; this comparator is passed AST nodes
     *   from a JLS2 AST
	 * @param options bitwise-or of option flags; <code>0</code> for default
	 * behavior (reserved for future growth)
	 * @param monitor the progress monitor to notify, or <code>null</code> if
	 * none
	 * @exception JavaModelException if the compilation unit could not be
	 * sorted. Reasons include:
	 * <ul>
	 * <li> The given compilation unit does not exist (ELEMENT_DOES_NOT_EXIST)</li>
	 * <li> The given compilation unit is not a working copy (INVALID_ELEMENT_TYPES)</li>
	 * <li> A <code>CoreException</code> occurred while accessing the underlying
	 * resource
	 * </ul>
	 * @exception IllegalArgumentException if the given compilation unit is null
	 * or if the given comparator is null.
	 * @see org.aspectj.org.eclipse.jdt.core.dom.BodyDeclaration
	 * @see #RELATIVE_ORDER
     * @deprecated Clients should port their code to use the new JLS3 AST API and call
     *    {@link #sort(int, ICompilationUnit, int[], Comparator, int, IProgressMonitor)
     *    CompilationUnitSorter.sort(AST.JLS3, compilationUnit, positions, comparator, options, monitor)}
     *    instead of using this method.
	 */
	public static void sort(ICompilationUnit compilationUnit,
	        int[] positions,
	        Comparator comparator,
	        int options,
	        IProgressMonitor monitor) throws JavaModelException {
		sort(AST.JLS2, compilationUnit, positions, comparator, options, monitor);
	}

    /**
     * Reorders the declarations in the given compilation unit according to
     * the specified AST level. The caller is responsible for arranging in
     * advance that the given compilation unit is a working copy, and for
     * saving the changes afterwards.
     * <p>
     * <b>Note:</b> Reordering the members within a type declaration might be
     * more than a cosmetic change and could have potentially serious
     * repercussions. Firstly, the order in which the fields of a type are
     * initialized is significant in the Java language; reordering fields
     * and initializers may result in compilation errors or change the execution
     * behavior of the code. Secondly, reordering a class's members may affect
     * how its instances are serialized. This operation should therefore be used
     * with caution and due concern for potential negative side effects.
     * </p>
     * <p>
     * The optional <code>positions</code> array contains a non-decreasing
     * ordered list of character-based source positions within the compilation
     * unit's source code string. Upon return from this method, the positions in
     * the array reflect the corresponding new locations in the modified source
     * code string. Note that this operation modifies the given array in place.
     * </p>
     * <p>
     * The <code>compare</code> method of the given comparator is passed pairs
     * of body declarations (subclasses of <code>BodyDeclaration</code>)
     * representing body declarations at the same level. The nodes are from an
     * AST of the specified level
     * ({@link org.aspectj.org.eclipse.jdt.core.dom.ASTParser#newParser(int)}. Clients
     * will generally specify the latest available <code>{@link AST}.JLS*</code> constant since that will
     * cover all constructs found in all version of Java source code.
     * The comparator is called on body declarations of nested classes, including
     * anonymous and local classes, but always at the same level. Clients need to provide
     * a comparator implementation (there is no standard comparator). The
     * <code>RELATIVE_ORDER</code> property attached to these AST nodes afforts
     * the comparator a way to preserve the original relative order.
     * </p>
     * <p>
     * The body declarations passed as parameters to the comparator
     * always carry at least the following minimal signature information:
     * <br>
     * <table border="1" width="80%" cellpadding="5">
     *    <tr>
     *      <td width="20%"><code>TypeDeclaration</code></td>
     *      <td width="50%"><code>modifiers, isInterface, name, superclass,
     *        superInterfaces, typeParameters<br>
     *        RELATIVE_ORDER property</code></td>
     *    </tr>
     *    <tr>
     *      <td width="20%"><code>FieldDeclaration</code></td>
     *      <td width="50%"><code>modifiers, type, fragments
     *        (VariableDeclarationFragments
     *        with name only)<br>
     *        RELATIVE_ORDER property</code></td>
     *    </tr>
     *    <tr>
     *      <td width="20%"><code>MethodDeclaration</code></td>
     *      <td width="50%"><code>modifiers, isConstructor, returnType, name,
     *        typeParameters, parameters
     *        (SingleVariableDeclarations with name, type, and modifiers only),
     *        thrownExceptions<br>
     *        RELATIVE_ORDER property</code></td>
     *    </tr>
     *    <tr>
     *      <td width="20%"><code>Initializer</code></td>
     *      <td width="50%"><code>modifiers<br>
     *        RELATIVE_ORDER property</code></td>
     *    </tr>
     *    <tr>
     *      <td width="20%"><code>AnnotationTypeDeclaration</code></td>
     *      <td width="50%"><code>modifiers, name<br>
     *        RELATIVE_ORDER property</code></td>
     *    </tr>
     *    <tr>
     *      <td width="20%"><code>AnnotationTypeMemberDeclaration</code></td>
     *      <td width="50%"><code>modifiers, name, type, default<br>
     *        RELATIVE_ORDER property</code></td>
     *    </tr>
     *    <tr>
     *      <td width="20%"><code>EnumDeclaration</code></td>
     *      <td width="50%"><code>modifiers, name, superInterfaces<br>
     *        RELATIVE_ORDER property</code></td>
     *    </tr>
     *    <tr>
     *      <td width="20%"><code>EnumConstantDeclaration</code></td>
     *      <td width="50%"><code>modifiers, name, arguments<br>
     *        RELATIVE_ORDER property</code></td>
     *    </tr>
     * </table>
     * Clients should not rely on the AST nodes being properly parented or on
     * having source range information. (Future releases may provide options
     * for requesting additional information like source positions, full ASTs,
     * non-recursive sorting, etc.)
     * </p>
     *
     * @param level the AST level; one of the <code>{@link AST}.JLS*</code> constants
     * @param compilationUnit the given compilation unit, which must be a
     * working copy
     * @param positions an array of source positions to map, or
     * <code>null</code> if none. If supplied, the positions must
     * character-based source positions within the original source code for
     * the given compilation unit, arranged in non-decreasing order.
     * The array is updated in place when this method returns to reflect the
     * corresponding source positions in the permuted source code string
     * (but not necessarily any longer in non-decreasing order).
     * @param comparator the comparator capable of ordering
     *   <code>BodyDeclaration</code>s; this comparator is passed AST nodes
     *   from an AST of the specified AST level
     * @param options bitwise-or of option flags; <code>0</code> for default
     * behavior (reserved for future growth)
     * @param monitor the progress monitor to notify, or <code>null</code> if
     * none
     * @exception JavaModelException if the compilation unit could not be
     * sorted. Reasons include:
     * <ul>
     * <li> The given compilation unit does not exist (ELEMENT_DOES_NOT_EXIST)</li>
     * <li> The given compilation unit is not a working copy (INVALID_ELEMENT_TYPES)</li>
     * <li> A <code>CoreException</code> occurred while accessing the underlying
     * resource
     * </ul>
     * @exception IllegalArgumentException if the given compilation unit is null
     * or if the given comparator is null, or if <code>level</code> is not one of
     * the AST JLS level constants.
     * @see org.aspectj.org.eclipse.jdt.core.dom.BodyDeclaration
     * @see #RELATIVE_ORDER
     * @since 3.1
     */
    public static void sort(int level, ICompilationUnit compilationUnit,
            int[] positions,
            Comparator comparator,
            int options,
            IProgressMonitor monitor) throws JavaModelException {
        if (compilationUnit == null || comparator == null) {
            throw new IllegalArgumentException();
        }
        checkASTLevel(level);
        ICompilationUnit[] compilationUnits = new ICompilationUnit[] { compilationUnit };
        SortElementsOperation operation = new SortElementsOperation(level, compilationUnits, positions, comparator);
        operation.runOperation(monitor);
    }

	/**
	 * Reorders the declarations in the given compilation unit according to the
	 * specified comparator. The caller is responsible for arranging in advance
	 * that the given compilation unit is a working copy, and for applying the
	 * returned TextEdit afterwards.
	 * <p>
	 * <b>Note:</b> Reordering the members within a type declaration might be
	 * more than a cosmetic change and could have potentially serious
	 * repercussions. Firstly, the order in which the fields of a type are
	 * initialized is significant in the Java language; reordering fields and
	 * initializers may result in compilation errors or change the execution
	 * behavior of the code. Secondly, reordering a class's members may affect
	 * how its instances are serialized. This operation should therefore be used
	 * with caution and due concern for potential negative side effects.
	 * </p>
	 * <p>
	 * The <code>compare</code> method of the given comparator is passed pairs
	 * of body declarations (subclasses of <code>BodyDeclaration</code>)
	 * representing body declarations at the same level.
	 * The comparator is called on body declarations of nested classes,
	 * including anonymous and local classes, but always at the same level.
	 * Clients need to provide a comparator implementation (there is no standard
	 * comparator). The <code>RELATIVE_ORDER</code> property attached to these
	 * AST nodes affords the comparator a way to preserve the original relative
	 * order.
	 * </p>
	 * <p>
	 * The body declarations passed as parameters to the comparator always carry
	 * at least the following minimal signature information: <br>
	 * <table border="1" width="80%" cellpadding="5">
	 * <tr>
	 * <td width="20%"><code>TypeDeclaration</code></td>
	 * <td width="50%"><code>modifiers, isInterface, name, superclass,
	 *        superInterfaces, typeParameters<br>
	 *        RELATIVE_ORDER property</code></td>
	 * </tr>
	 * <tr>
	 * <td width="20%"><code>FieldDeclaration</code></td>
	 * <td width="50%"><code>modifiers, type, fragments
	 *        (VariableDeclarationFragments
	 *        with name only)<br>
	 *        RELATIVE_ORDER property</code></td>
	 * </tr>
	 * <tr>
	 * <td width="20%"><code>MethodDeclaration</code></td>
	 * <td width="50%"><code>modifiers, isConstructor, returnType, name,
	 *        typeParameters, parameters
	 *        (SingleVariableDeclarations with name, type, and modifiers only),
	 *        thrownExceptions<br>
	 *        RELATIVE_ORDER property</code></td>
	 * </tr>
	 * <tr>
	 * <td width="20%"><code>Initializer</code></td>
	 * <td width="50%"><code>modifiers<br>
	 *        RELATIVE_ORDER property</code></td>
	 * </tr>
	 * <tr>
	 * <td width="20%"><code>AnnotationTypeDeclaration</code></td>
	 * <td width="50%"><code>modifiers, name<br>
	 *        RELATIVE_ORDER property</code></td>
	 * </tr>
	 * <tr>
	 * <td width="20%"><code>AnnotationTypeMemberDeclaration</code></td>
	 * <td width="50%"><code>modifiers, name, type, default<br>
	 *        RELATIVE_ORDER property</code></td>
	 * </tr>
	 * <tr>
	 * <td width="20%"><code>EnumDeclaration</code></td>
	 * <td width="50%"><code>modifiers, name, superInterfaces<br>
	 *        RELATIVE_ORDER property</code></td>
	 * </tr>
	 * <tr>
	 * <td width="20%"><code>EnumConstantDeclaration</code></td>
	 * <td width="50%"><code>modifiers, name, arguments<br>
	 *        RELATIVE_ORDER property</code></td>
	 * </tr>
	 * </table>
	 * </p>
	 *
	 * @param unit
	 *            the CompilationUnit to sort
	 * @param comparator
	 *            the comparator capable of ordering
	 *            <code>BodyDeclaration</code>s; this comparator is passed
	 *            AST nodes from an AST of the specified AST level
	 * @param options
	 *            bitwise-or of option flags; <code>0</code> for default
	 *            behavior (reserved for future growth)
	 * @param group
	 *            the text edit group to use when generating text edits, or <code>null</code>
	 * @param monitor
	 *            the progress monitor to notify, or <code>null</code> if none
	 * @return a TextEdit describing the required edits to do the sort, or <code>null</code>
	 *            if sorting is not required
	 * @exception JavaModelException
	 *                if the compilation unit could not be sorted. Reasons
	 *                include:
	 *                <ul>
	 *                <li> The given unit was not created from a ICompilationUnit (INVALID_ELEMENT_TYPES)</li>
	 *                </ul>
	 * @exception IllegalArgumentException
	 *                if the given compilation unit is null or if the given
	 *                comparator is null, or if <code>options</code> is not one
	 *                of the supported levels.
	 * @see org.aspectj.org.eclipse.jdt.core.dom.BodyDeclaration
	 * @see #RELATIVE_ORDER
	 * @since 3.3
	 */
	public static TextEdit sort(CompilationUnit unit,
			Comparator comparator,
			int options,
			TextEditGroup group,
			IProgressMonitor monitor) throws JavaModelException {
		if (unit == null || comparator == null) {
			throw new IllegalArgumentException();
		}
		SortElementsOperation operation = new SortElementsOperation(unit.getAST().apiLevel(), new IJavaElement[] { unit.getJavaElement() }, null, comparator);
		return operation.calculateEdit(unit, group);
	}
}
