/*******************************************************************************
 * Copyright (c) 2005, 2007 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.internal;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;


/**
 * Various helper methods for generating names.
 */
public final class NameTools {

	/**
	 * Given a "root" name and a set of existing names, generate a unique,
	 * Java-legal name that is either the "root" name or some variation on
	 * the "root" name (e.g. "root2", "root3",...).
	 * The names are case-sensitive.
	 */
	public static String uniqueJavaNameFor(String rootName, Iterator<String> existingNames) {
		Collection<String> existingNames2 = CollectionTools.set(existingNames);
		existingNames2.addAll(JAVA_RESERVED_WORDS_SET);
		return uniqueNameFor(rootName, existingNames2, rootName);
	}
	
	/**
	 * Given a "root" name and a set of existing names, generate a unique,
	 * Java-legal name that is either the "root" name or some variation on
	 * the "root" name (e.g. "root2", "root3",...).
	 * The names are case-sensitive.
	 */
	public static String uniqueJavaNameFor(String rootName, Collection<String> existingNames) {
		Collection<String> existingNames2 = new HashSet<String>(existingNames);
		existingNames2.addAll(JAVA_RESERVED_WORDS_SET);
		return uniqueNameFor(rootName, existingNames2, rootName);
	}

	/**
	 * Given a "root" name and a set of existing names, generate a unique
	 * name that is either the "root" name or some variation on the "root"
	 * name (e.g. "root2", "root3",...). The names are case-sensitive.
	 */
	public static String uniqueNameFor(String rootName, Iterator<String> existingNames) {
		return uniqueNameFor(rootName, CollectionTools.set(existingNames));
	}
	
	/**
	 * Given a "root" name and a set of existing names, generate a unique
	 * name that is either the "root" name or some variation on the "root"
	 * name (e.g. "root2", "root3",...). The names are case-sensitive.
	 */
	public static String uniqueNameFor(String rootName, Collection<String> existingNames) {
		return uniqueNameFor(rootName, existingNames, rootName);
	}

	/**
	 * Given a "root" name and a set of existing names, generate a unique
	 * name that is either the "root" name or some variation on the "root"
	 * name (e.g. "root2", "root3",...). The names are NOT case-sensitive.
	 */
	public static String uniqueNameForIgnoreCase(String rootName, Iterator<String> existingNames) {
		return uniqueNameForIgnoreCase(rootName, CollectionTools.set(existingNames));
	}

	/**
	 * Given a "root" name and a set of existing names, generate a unique
	 * name that is either the "root" name or some variation on the "root"
	 * name (e.g. "root2", "root3",...). The names are NOT case-sensitive.
	 */
	public static String uniqueNameForIgnoreCase(String rootName, Collection<String> existingNames) {
		return uniqueNameFor(rootName, convertToLowerCase(existingNames), rootName.toLowerCase());
	}

	/**
	 * use the suffixed "template" name to perform the comparisons, but RETURN
	 * the suffixed "root" name; this allows case-insensitive comparisons
	 * (i.e. the "template" name has been morphed to the same case as
	 * the "existing" names, while the "root" name has not, but the "root" name
	 * is what the client wants morphed to be unique)
	 */
	private static String uniqueNameFor(String rootName, Collection<String> existingNames, String templateName) {
		if ( ! existingNames.contains(templateName)) {
			return rootName;
		}
		String uniqueName = templateName;
		for (int suffix = 2; true; suffix++) {
			if ( ! existingNames.contains(uniqueName + suffix)) {
				return rootName.concat(String.valueOf(suffix));
			}
		}
	}

	/**
	 * Convert the specified collection of strings to a collection of the same
	 * strings converted to lower case.
	 */
	private static Collection<String> convertToLowerCase(Collection<String> strings) {
		Collection<String> result = new HashBag<String>(strings.size());
		for (String string : strings) {
			result.add(string.toLowerCase());
		}
		return result;
	}

	/**
	 * Build a fully-qualified name for the specified database object.
	 * Variations:
	 *     catalog.schema.name
	 *     catalog..name
	 *     schema.name
	 *     name
	 */
	public static String buildQualifiedDatabaseObjectName(String catalog, String schema, String name) {
		if (name == null) {
			throw new IllegalArgumentException();
		}
		if ((catalog == null) && (schema == null)) {
			return name;
		}

		StringBuffer sb = new StringBuffer(100);
		if (catalog != null) {
			sb.append(catalog);
			sb.append('.');
		}
		if (schema != null) {
			sb.append(schema);
		}
		sb.append('.');
		sb.append(name);
		return sb.toString();
	}

	/**
	 * The set of reserved words in the Java programming language.
	 * These words cannot be used as identifiers (i.e. names).
	 * http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
	 */
	public static final String[] JAVA_RESERVED_WORDS = new String[] {
				"abstract",
				"assert",  // jdk 1.4
				"boolean",
				"break",
				"byte",
				"case",
				"catch",
				"char",
				"class",
				"const",  // unused
				"continue",
				"default",
				"do",
				"double",
				"else",
				"enum",  // jdk 5.0
				"extends",
				"false",
				"final",
				"finally",
				"float",
				"for",
				"goto",  // unused
				"if",
				"implements",
				"import",
				"instanceof",
				"int",
				"interface",
				"long",
				"native",
				"new",
				"null",
				"package",
				"private",
				"protected",
				"public",
				"return",
				"short",
				"static",
				"strictfp",  // jdk 1.2
				"super",
				"switch",
				"synchronized",
				"this",
				"throw",
				"throws",
				"transient",
				"true",
				"try",
				"void",
				"volatile",
				"while"
			};

	/**
	 * The set of reserved words in the Java programming language.
	 * These words cannot be used as identifiers (i.e. names).
	 * http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
	 */
	public static final Set<String> JAVA_RESERVED_WORDS_SET = CollectionTools.set(JAVA_RESERVED_WORDS);

	/**
	 * Return the set of Java programming language reserved words.
	 * These words cannot be used as identifiers (i.e. names).
	 * http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
	 */
	public static Iterator<String> javaReservedWords() {
		return new ArrayIterator<String>(JAVA_RESERVED_WORDS);
	}

	/**
	 * Convert the specified string to a valid Java identifier
	 * by substituting an underscore '_' for any invalid characters
	 * in the string and capitalizing the string if it is a Java
	 * reserved word.
	 */
	public static String convertToJavaIdentifier(String string) {
		return convertToJavaIdentifier(string, '_');
	}

	/**
	 * Convert the specified string to a valid Java identifier
	 * by substituting the specified character for any invalid characters
	 * in the string and capitalizing the string if it is a Java
	 * reserved word.
	 */
	public static String convertToJavaIdentifier(String string, char c) {
		if (string.length() == 0) {
			return string;
		}
		if (JAVA_RESERVED_WORDS_SET.contains(string)) {
			// a reserved words is a valid identifier, we just need to tweak it a bit
			return StringTools.capitalize(string);
		}
		return new String(convertToJavaIdentifierInternal(string.toCharArray(), c));
	}

	/**
	 * Convert the specified string to a valid Java identifier
	 * by substituting an underscore '_' for any invalid characters
	 * in the string and capitalizing the string if it is a Java
	 * reserved word.
	 */
	public static char[] convertToJavaIdentifier(char[] string) {
		return convertToJavaIdentifier(string, '_');
	}

	/**
	 * Convert the specified string to a valid Java identifier
	 * by substituting the specified character for any invalid characters
	 * in the string and capitalizing the string if it is a Java
	 * reserved word.
	 */
	public static char[] convertToJavaIdentifier(char[] string, char c) {
		int length = string.length;
		if (length == 0) {
			return string;
		}
		if (JAVA_RESERVED_WORDS_SET.contains(new String(string))) {
			// a reserved words is a valid identifier, we just need to tweak it a bit
			return StringTools.capitalize(string);
		}
		return convertToJavaIdentifierInternal(string, c);
	}

	private static char[] convertToJavaIdentifierInternal(char[] string, char c) {
		if ( ! Character.isJavaIdentifierStart(string[0])) {
			if ( ! Character.isJavaIdentifierStart(c)) {
				throw new IllegalArgumentException("invalid Java identifier start char: '" + c + "'");
			}
			string[0] = c;
		}
		if ( ! Character.isJavaIdentifierPart(c)) {
			throw new IllegalArgumentException("invalid Java identifier part char: '" + c + "'");
		}
		for (int i = string.length; i-- > 1; ) {  // NB: end with 1
			if ( ! Character.isJavaIdentifierPart(string[i])) {
				string[i] = c;
			}
		}
		return string;
	}


	// ********** constructor **********

	/**
	 * Suppress default constructor, ensuring non-instantiability.
	 */
	private NameTools() {
		super();
		throw new UnsupportedOperationException();
	}

}
