/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 *
 * Copyright 20038 Technical University Berlin, Germany.
 *
 * 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/
 *
 * SPDX-License-Identifier: EPL-2.0
 * $Id: Sorting.java 23417 2010-02-03 20:13:55Z stephan $
 *
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 *
 * Contributors:
 * Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.internal.core.compiler.util;

import java.util.Arrays;
import java.util.Comparator;

import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;

/**
 * Sorting utilities.
 *
 * @author stephan
 * @since 1.2.1
 */
public class Sorting {

	/**
	 * Topological sort for member types with depth first search.
	 * Guarantee: supertypes come before subtypes.
	 */
	public static void sortMemberTypes(SourceTypeBinding enclosing) {
		int len = enclosing.memberTypes.length;

		ReferenceBinding[] unsorted = new ReferenceBinding[len];
		ReferenceBinding[] sorted = new ReferenceBinding[len];
		System.arraycopy(enclosing.memberTypes, 0, unsorted, 0, len);
		
		int o = 0;
		for(int i=0; i<len; i++)
			o = sort(enclosing, unsorted, i, sorted, o);

		enclosing.memberTypes = sorted;
	}
	// Transfer input[i] and all its supers into output[o] ff.
	private static int sort(ReferenceBinding enclosing,
							ReferenceBinding[] input, int i,
							ReferenceBinding[] output, int o)
	{
		if (input[i] == null)
			return o;

		ReferenceBinding superclass = input[i].superclass();
		o = sortSuper(enclosing, superclass, input, output, o);

		for (ReferenceBinding superIfc : input[i].superInterfaces())
			o = sortSuper(enclosing, superIfc, input, output, o);

		// done with supers, now input[i] can safely be transferred:
		output[o++] = input[i];
		input[i] = null;

		return o;
	}
	// if superclass is within the set of member types to sort,
	// transfer it and all its supers to output[o] ff.
	private static int sortSuper(ReferenceBinding enclosing,
						  		 ReferenceBinding superclass,
						  		 ReferenceBinding[] input,
						  		 ReferenceBinding[] output, int o)
	{
		if (   superclass != null // inspecting super of Confined?
			&& superclass.id != TypeIds.T_JavaLangObject
			&& TypeBinding.equalsEquals(superclass.enclosingType(), enclosing)) // is super within scope?
		{
			// search superclass within input:
			int j = 0;
			for(j=0; j<input.length; j++)
				if (TypeBinding.equalsEquals(input[j], superclass))
					break;
			if (j < input.length)
				// depth first traversal:
				o = sort(enclosing, input, j, output, o);
			// otherwise assume super was already transferred.
		}
		return o;
	}

	// --- similar for role models:
	
	public static RoleModel[] sortRoles(RoleModel[] unsorted) {
		int len = unsorted.length;
		
		RoleModel[] sorted = new RoleModel[len];
		int o = 0;
		for(int i=0; i<len; i++)
			o = sort(unsorted, i, sorted, o);
		// also consider the base hierarchy, but for roles bound to
		// the same base keep the existing order.
		Arrays.sort(sorted, new Comparator<RoleModel>() {
			@Override
			public int compare(RoleModel o1, RoleModel o2) {
				ReferenceBinding b1 = o1.getBaseTypeBinding();
				ReferenceBinding b2 = o2.getBaseTypeBinding();
				if (TypeBinding.equalsEquals(b1, b2))
					return 0;
				if (b1 != null && b1.id != TypeIds.T_JavaLangObject) {
					if (b2 == null || b2.id == TypeIds.T_JavaLangObject)
						return 1;
					if (b1.isCompatibleWith(b2))
						return 1;
					if (b2.isCompatibleWith(b1))
						return -1;
				} else {
					if (b2 != null && b2.id != TypeIds.T_JavaLangObject)
						return -1;
				}
				return 0;
			}
		});
		
		return sorted;
	}
	
	// Transfer input[i] and all its supers into output[o] ff.
	private static int sort(RoleModel[] input, int i,
							RoleModel[] output, int o)
	{
		if (input[i] == null || input[i].getBinding() == null)
			return o;
		
		ReferenceBinding inBinding = input[i].getBinding();
		ReferenceBinding superclass = inBinding.superclass();
		o = sortSuper(superclass, input, output, o);

		for (ReferenceBinding superIfc : inBinding.superInterfaces())
			o = sortSuper(superIfc, input, output, o);

		// done with supers, now input[i] can safely be transferred:
		output[o++] = input[i];
		input[i] = null;

		return o;
	}
	// if superclass is within the set of member types to sort,
	// transfer it and all its supers to output[o] ff.
	private static int sortSuper(ReferenceBinding superclass,
						  		 RoleModel[] input,
						  		 RoleModel[] output, int o)
	{
		if (   superclass != null // inspecting super of Confined?
			&& superclass.id != TypeIds.T_JavaLangObject) // is super within scope?
		{
			boolean inScope = false;
			for (RoleModel rm : input)
				if (rm != null && TypeBinding.equalsEquals(rm.getBinding(), superclass)) {
					inScope = true;
					break;
				}
			if (inScope) {
					
				// search superclass within input:
				int j = 0;
				for(j=0; j<input.length; j++)
					if (input[j] != null && TypeBinding.equalsEquals(input[j].getBinding(), superclass))
						break;
				if (j < input.length)
					// depth first traversal:
					o = sort(input, j, output, o);
				// otherwise assume super was already transferred.
			}
		}
		return o;
	}
	
	/** Apply the sorting from member type bindings to their ASTs, too. */
	public static void sortMemberTypes(TypeDeclaration typeDeclaration) {
		if (typeDeclaration.memberTypes == null) return;
		ReferenceBinding[] bindings = typeDeclaration.binding.memberTypes;
		TypeDeclaration[] unsorted = typeDeclaration.memberTypes;
		TypeDeclaration[] newMembers = new TypeDeclaration[unsorted.length];
		int l = 0;
		allMembers: for (int i=0; i<bindings.length; i++) {
			ReferenceBinding current = bindings[i];
			if (current.isBinaryBinding()) 
				continue; // no AST: phantom or reused rofi
			// find corresponding AST
			for (int j=0; j<unsorted.length; j++) {
				if (TypeBinding.equalsEquals(unsorted[j].binding, current)) {
					newMembers[l++] = unsorted[j];
					continue allMembers;
				}
			}
			throw new InternalCompilerError("Unmatched member type "+String.valueOf(current.readableName())); //$NON-NLS-1$
		}
		if (l<newMembers.length)
			throw new InternalCompilerError("Not all member types matched: "+l); //$NON-NLS-1$
		typeDeclaration.memberTypes = newMembers;
	}
}
