/*******************************************************************************
 * Copyright (c) 2009, 2010 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.core.internal.jpa2;

import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;
import java.util.Map.Entry;

import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jpt.core.JptCorePlugin;
import org.eclipse.jpt.core.context.AttributeMapping;
import org.eclipse.jpt.core.context.PersistentAttribute;
import org.eclipse.jpt.core.context.PersistentType;
import org.eclipse.jpt.core.jpa2.JpaProject2_0;
import org.eclipse.jpt.core.jpa2.context.AttributeMapping2_0;
import org.eclipse.jpt.core.jpa2.context.MetamodelField;
import org.eclipse.jpt.core.jpa2.context.PersistentType2_0;
import org.eclipse.jpt.core.jpa2.resource.java.JPA2_0;
import org.eclipse.jpt.core.jpa2.resource.java.JavaResourcePersistentType2_0;
import org.eclipse.jpt.utility.Filter;
import org.eclipse.jpt.utility.internal.ClassName;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.IndentingPrintWriter;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.Transformer;
import org.eclipse.jpt.utility.internal.iterables.FilteringIterable;
import org.eclipse.jpt.utility.internal.iterables.TransformationIterable;

import com.ibm.icu.text.Collator;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;

/**
 * For now, the "synchronization" is simple brute-force: we generate the source
 * code and then compare it with what is already present in the file.
 * If the new source is different, we replace the file contents; otherwise, we
 * leave the file unchanged.
 */
@SuppressWarnings("nls")
public class GenericPersistentTypeMetamodelSynchronizer
	implements PersistentType2_0.MetamodelSynchronizer
{
	protected final PersistentType2_0 persistentType;


	public GenericPersistentTypeMetamodelSynchronizer(PersistentType2_0 persistentType) {
		super();
		this.persistentType = persistentType;
	}

	public IFile getFile() {
		return (IFile) this.getPackageFragment().getCompilationUnit(this.getFileName()).getResource();
	}


	// ********** synchronize **********

	public void synchronize() {
		try {
			this.synchronize_();
		} catch (JavaModelException ex) {
			JptCorePlugin.log(ex);
		}
	}

	protected void synchronize_() throws JavaModelException {
		IPackageFragment pkg = this.getPackageFragment();
		String fileName = this.getFileName();

		ICompilationUnit compilationUnit = pkg.getCompilationUnit(fileName);
		if (compilationUnit.exists()) {
			// overwrite existing file if it has changed (ignoring the timestamp)
			String newSource = this.buildSource(compilationUnit);
			if (newSource != null) {
				pkg.createCompilationUnit(fileName, newSource, true, null);  // true=force
			}
		} else {
			// write a new file, creating the package folders if necessary
			if ( ! pkg.exists()) {
				this.getSourceFolder().createPackageFragment(pkg.getElementName(), true, null);  // true=force
			}
			pkg.createCompilationUnit(fileName, this.buildSource(), false, null);  // false=no force
		}
	}

	/**
	 * pre-condition: the compilation unit exists
	 * 
	 * return null if the old source is not to be replaced
	 */
	protected String buildSource(ICompilationUnit compilationUnit) throws JavaModelException {
		IFile file = (IFile) compilationUnit.getResource();
		JavaResourcePersistentType2_0 genType = this.getJpaProject().getGeneratedMetamodelType(file);
		if (genType == null) {
			return null;  // the file exists, but its source is not a generated metamodel class
		}

		String oldSource = compilationUnit.getSource();
		int oldLength = oldSource.length();

		String newSource = this.buildSource();
		int newLength = newSource.length();
		if (newLength != oldLength) {
			return newSource;
		}

		String date = genType.getGeneratedAnnotation().getDate();  // if we get here, this will be non-empty
		int dateBegin = oldSource.indexOf(date);
		if (dateBegin == -1) {
			return null;  // hmmm...
		}
		int dateEnd = dateBegin + date.length();
		if (dateEnd > oldLength) {
			return null;  // hmmm...
		}

		if (newSource.regionMatches(0, oldSource, 0, dateBegin) &&
					newSource.regionMatches(dateEnd, oldSource, dateEnd, oldLength - dateEnd)) {
			return null;
		}
		return newSource;
	}


	// ********** package/file **********

	protected IPackageFragment getPackageFragment() {
		return this.getSourceFolder().getPackageFragment(this.getPackageName());
	}

	protected IPackageFragmentRoot getSourceFolder() {
		return this.getJpaProject().getMetamodelPackageFragmentRoot();
	}

	protected JpaProject2_0 getJpaProject() {
		return (JpaProject2_0) this.persistentType.getJpaProject();
	}

	// TODO
	protected String getPackageName() {
		// the default is to store the metamodel in the same package as the model
		return ClassName.getPackageName(this.getMetamodelClassName());
	}

	protected String getFileName() {
		return ClassName.getSimpleName(this.getMetamodelClassName()) + ".java";
	}

	protected String getMetamodelClassName() {
		return this.buildMetamodelClassName(this.persistentType.getName());
	}

	// TODO
	protected String buildMetamodelClassName(String className) {
		// the default is to simply append an underscore to the model class name
		return className + '_';
	}


	// ********** source code **********

	/**
	 * build the "body" source first; then build the "package" and "imports" source
	 * and concatenate the "body" source to it
	 */
	protected String buildSource() {
		// build the body source first so we can gather up the import statements
		BodySourceWriter bodySourceWriter = this.buildBodySourceWriter();

		StringWriter sw = new StringWriter(bodySourceWriter.getLength() + 2000);
		PrintWriter pw = new PrintWriter(sw);
		this.printPackageAndImportsOn(pw, bodySourceWriter);
		pw.print(bodySourceWriter.getSource());
		return sw.toString();
	}

	protected BodySourceWriter buildBodySourceWriter() {
		BodySourceWriter pw = new BodySourceWriter(this.getPackageName(), this.getMetamodelClassName());
		this.printBodySourceOn(pw);
		return pw;
	}

	protected void printBodySourceOn(BodySourceWriter pw) {
		this.printClassDeclarationOn(pw);
		pw.print(" {");
		pw.println();

		pw.indent();
			this.printAttributesOn(pw);
		pw.undent();

		pw.print('}');
		pw.println();  // EOF
	}


	// ********** class declaration **********

	protected void printClassDeclarationOn(BodySourceWriter pw) {
		this.printGeneratedAnnotationOn(pw);
		this.printStaticMetamodelAnnotationOn(pw);

		pw.print("public class ");
		pw.printTypeDeclaration(this.getMetamodelClassName());
		PersistentType superPersistentType = this.persistentType.getSuperPersistentType();
		if (superPersistentType != null) {
			pw.print(" extends ");
			pw.printTypeDeclaration(this.buildMetamodelClassName(superPersistentType.getName()));
		}
	}

	protected void printStaticMetamodelAnnotationOn(BodySourceWriter pw) {
		pw.printAnnotation(JPA2_0.STATIC_METAMODEL);
		pw.print('(');
		pw.printTypeDeclaration(this.persistentType.getName());
		pw.print(".class");
		pw.print(')');
		pw.println();
	}

	protected void printGeneratedAnnotationOn(BodySourceWriter pw) {
		pw.printAnnotation("javax.annotation.Generated");
		pw.print('(');
		pw.print("value=");
		pw.printStringLiteral(JavaResourcePersistentType2_0.METAMODEL_GENERATED_ANNOTATION_VALUE);
		pw.print(", ");
		pw.print("date=");
		pw.printStringLiteral(format(new Date()));
		pw.print(')');
		pw.println();
	}

	/**
	 * {@link SimpleDateFormat} is not thread-safe.
	 */
	protected static synchronized String format(Date date) {
		return DATE_FORMAT.format(date);
	}
	/**
	 * Recommended date format is ISO 8601.
	 * @see javax.annotation.Generated
	 */
	private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");


	// ********** attributes **********

	protected void printAttributesOn(BodySourceWriter pw) {
		for (Iterator<PersistentAttribute> stream = this.persistentType.attributes(); stream.hasNext(); ) {
			this.printAttributeOn(stream.next(), pw);
		}
	}

	protected void printAttributeOn(PersistentAttribute persistentAttribute, BodySourceWriter pw) {
		AttributeMapping attributeMapping = persistentAttribute.getMapping();
		if (attributeMapping != null) {  // probably shouldn't be null?
			this.printAttributeMappingOn(attributeMapping, pw);
		}
	}

	protected void printAttributeMappingOn(AttributeMapping attributeMapping, BodySourceWriter pw) {
		MetamodelField field = ((AttributeMapping2_0) attributeMapping).getMetamodelField();
		if (field != null) {
			this.printFieldOn(field, pw);
		}
	}

	protected void printFieldOn(MetamodelField field, BodySourceWriter pw) {
		for (String modifier : field.getModifiers()) {
			pw.print(modifier);
			pw.print(' ');
		}
		pw.printTypeDeclaration(field.getTypeName());
		pw.print('<');
		for (Iterator<String> stream = field.getTypeArgumentNames().iterator(); stream.hasNext(); ) {
			pw.printTypeDeclaration(stream.next());
			if (stream.hasNext()) {
				pw.print(", ");
			}
		}
		pw.print('>');
		pw.print(' ');
		pw.print(field.getName());
		pw.print(';');
		pw.println();
	}


	// ********** package and imports **********

	protected void printPackageAndImportsOn(PrintWriter pw, BodySourceWriter bodySourceWriter) {
		if (this.getPackageName().length() != 0) {
			pw.print("package ");
			pw.print(this.getPackageName());
			pw.print(';');
			pw.println();
			pw.println();
		}

		for (String import_ : bodySourceWriter.getImports()) {
			pw.print("import ");
			pw.print(import_);
			pw.print(';');
			pw.println();
		}
		pw.println();
	}


	// ********** source writer **********

	/**
	 * Extend IndentingPrintWriter with some methods that facilitate building
	 * class source code.
	 */
	protected static class BodySourceWriter
		extends IndentingPrintWriter
	{
		protected final String packageName;
		protected final String className;
		// key = short class name; value = import package
		protected final HashMap<String, ImportPackage> imports = new HashMap<String, ImportPackage>();

		protected BodySourceWriter(String packageName, String className) {
			super(new StringWriter(2000));
			this.packageName = packageName;
			this.className = className;
		}

		protected String getSource() {
			return this.out.toString();
		}

		protected int getLength() {
			return ((StringWriter) this.out).getBuffer().length();
		}

		protected void printVisibility(String visibilityModifier) {
			if (visibilityModifier.length() != 0) {
				this.print(visibilityModifier);
				this.print(' ');
			}
		}

		protected void printAnnotation(String annotationName) {
			this.print('@');
			this.printTypeDeclaration(annotationName);
		}

		protected void printTypeDeclaration(String typeDeclaration) {
			this.print(this.buildImportedTypeDeclaration(typeDeclaration));
		}

		protected void printField(String fieldName, String typeDeclaration, String visibility) {
			this.printVisibility(visibility);
			this.printTypeDeclaration(typeDeclaration);
			this.print(' ');
			this.print(fieldName);
			this.print(';');
			this.println();
			this.println();
		}

		protected void printParameterizedField(String fieldName, String typeDeclaration, String parameterTypeDeclaration, String visibility) {
			this.printVisibility(visibility);
			this.printTypeDeclaration(typeDeclaration);
			this.print('<');
			this.printTypeDeclaration(parameterTypeDeclaration);
			this.print('>');
			this.print(' ');
			this.print(fieldName);
			this.print(';');
			this.println();
			this.println();
		}

		/**
		 * Convert the specified string to a String Literal and print it,
		 * adding the surrounding double-quotes and escaping characters
		 * as necessary.
		 */
		void printStringLiteral(String string) {
			StringTools.convertToJavaStringLiteralOn(string, this);
		}


		// ********** imports **********

		// ***** writing
		/**
		 * Return the specified class's "imported" name.
		 * The class declaration must be of the form:
		 *     "int"
		 *     "int[]" (not "[I")
		 *     "java.lang.Object"
		 *     "java.lang.Object[]" (not "[Ljava.lang.Object;")
		 *     "java.util.Map.Entry" (not "java.util.Map$Entry")
		 *     "java.util.Map.Entry[][]" (not "[[Ljava.util.Map$Entry;")
		 *     
		 * To really do this right, we would need to gather all the types from
		 * the "unamed" (default) package that were referenced in the
		 * compilation unit beforehand. *Any* collisions with one of these
		 * types would have to be fully qualified (whether it was from
		 * 'java.lang' or the same package as the current compilation unit).
		 * In other words, if we have any types from the "unnamed" package,
		 * results are unpredictable....
		 */
		protected String buildImportedTypeDeclaration(String typeDeclaration) {
			if (this.typeDeclarationIsMemberClass(typeDeclaration)) {
				// no need for an import, just return the partially-qualified name
				return this.buildMemberClassTypeDeclaration(typeDeclaration);
			}
			int last = typeDeclaration.lastIndexOf('.');
			String currentPackageName = (last == -1) ? "" : typeDeclaration.substring(0, last);
			String shortTypeDeclaration = typeDeclaration.substring(last + 1);
			String shortElementTypeName = shortTypeDeclaration;
			while (shortElementTypeName.endsWith("[]")) {
				shortElementTypeName = shortElementTypeName.substring(0, shortElementTypeName.length() - 2);
			}
			ImportPackage prev = this.imports.get(shortElementTypeName);
			if (prev == null) {
				// this is the first class with this short element type name
				this.imports.put(shortElementTypeName, new ImportPackage(currentPackageName));
				return shortTypeDeclaration;
			}
			if (prev.packageName.equals(currentPackageName)) {
				// this element type has already been imported
				return shortTypeDeclaration;
			}
			if (currentPackageName.equals(this.packageName) &&
					prev.packageName.equals("java.lang")) {
				// we force the 'java.lang' class to be explicitly imported
				prev.collision = true;
			}
			// another class with the same short element type name has been
			// previously imported, so this one must be used fully-qualified
			return typeDeclaration;
		}

		/**
		 * e.g. "foo.bar.Employee.PK" will return true
		 */
		protected boolean typeDeclarationIsMemberClass(String typeDeclaration) {
			return (typeDeclaration.length() > this.className.length())
					&& typeDeclaration.startsWith(this.className)
					&& (typeDeclaration.charAt(this.className.length()) == '.');
		}

		/**
		 * e.g. "foo.bar.Employee.PK" will return "Employee.PK"
		 * this prevents collisions with other imported classes (e.g. "joo.jar.PK")
		 */
		protected String buildMemberClassTypeDeclaration(String typeDeclaration) {
			int index = this.packageName.length();
			if (index != 0) {
				index++;  // bump past the '.'
			}
			return typeDeclaration.substring(index);
		}

		// ***** reading
		protected Iterable<String> getImports() {
			return this.getSortedRequiredImports();
		}

		/**
		 * transform our map entries to class names
		 */
		protected Iterable<String> getSortedRequiredImports() {
			return new TransformationIterable<Map.Entry<String, ImportPackage>, String>(this.getSortedRequiredImportEntries(), this.buildImportEntriesTransformer());
		}

		protected Transformer<Map.Entry<String, ImportPackage>, String> buildImportEntriesTransformer() {
			return IMPORT_ENTRIES_TRANSFORMER;
		}

		protected static final Transformer<Map.Entry<String, ImportPackage>, String> IMPORT_ENTRIES_TRANSFORMER = new ImportEntriesTransformer();

		protected static class ImportEntriesTransformer
			implements Transformer<Map.Entry<String, ImportPackage>, String>
		{
			public String transform(Entry<String, ImportPackage> importEntry) {
				String pkg = importEntry.getValue().packageName;
				String type = importEntry.getKey();
				StringBuilder sb = new StringBuilder(pkg.length() + 1 + type.length());
				sb.append(pkg);
				sb.append('.');
				sb.append(type);
				return sb.toString();
			}
		}

		/**
		 * sort by package first, then class (*not* by fully-qualified class name)
		 */
		protected Iterable<Map.Entry<String, ImportPackage>> getSortedRequiredImportEntries() {
			TreeSet<Map.Entry<String, ImportPackage>> sortedEntries = new TreeSet<Map.Entry<String, ImportPackage>>(this.buildImportEntriesComparator());
			CollectionTools.addAll(sortedEntries, this.getRequiredImportEntries());
			return sortedEntries;
		}

		protected Comparator<Map.Entry<String, ImportPackage>> buildImportEntriesComparator() {
			return IMPORT_ENTRIES_COMPARATOR;
		}

		protected static final Comparator<Map.Entry<String, ImportPackage>> IMPORT_ENTRIES_COMPARATOR = new ImportEntriesComparator();

		protected static class ImportEntriesComparator
			implements Comparator<Map.Entry<String, ImportPackage>>, Serializable
		{
			public int compare(Map.Entry<String, ImportPackage> e1, Map.Entry<String, ImportPackage> e2) {
				Collator collator = Collator.getInstance();
				int pkg = collator.compare(e1.getValue().packageName, e2.getValue().packageName);
				return (pkg == 0) ? collator.compare(e1.getKey(), e2.getKey()) : pkg;
			}
		}

		/**
		 * strip off any non-required imports (e.g. "java.lang.Object')
		 */
		protected Iterable<Map.Entry<String, ImportPackage>> getRequiredImportEntries() {
			return new FilteringIterable<Map.Entry<String, ImportPackage>>(this.imports.entrySet(), this.buildRequiredImportEntriesFilter());
		}

		protected Filter<Map.Entry<String, ImportPackage>> buildRequiredImportEntriesFilter() {
			return new RequiredImportEntriesFilter();
		}

		protected class RequiredImportEntriesFilter
			implements Filter<Map.Entry<String, ImportPackage>>
		{
			public boolean accept(Map.Entry<String, ImportPackage> importEntry) {
				return this.packageMustBeImported(importEntry.getValue());
			}

			protected boolean packageMustBeImported(ImportPackage importPackage) {
				String pkg = importPackage.packageName;
				if (pkg.equals("")) {
					// cannot import a type from the "unnamed" package
					return false;
				}
				if (pkg.equals("java.lang")) {
					// we must import from 'java.lang' if we also have a class in the same package
					return importPackage.collision;
				}
				if (pkg.equals(BodySourceWriter.this.packageName)) {
					// we never need to import a class from the same package
					return false;
				}
				return true;
			}
		}

		/**
		 * We need a 'collision' flag for when we encounter a class from
		 * 'java.lang' followed by a class from the current compilation unit's
		 * package. We will need to include the explicit import of the
		 * 'java.lang' class and all the references to the other class will
		 * have to be fully-qualified.
		 * 
		 * If the classes are encountered in the opposite order (i.e. the class
		 * from the current compilation unit's package followed by the class
		 * from 'java.lang'), we do *not* need to import the first class while
		 * all the references to the 'java.lang' class will be fully-qualified.
		 * 
		 * Unfortunately, we still have a problem: if we reference a class from
		 * 'java.lang' and there is a conflicting class from the current
		 * compilation unit's package (but that class is *not* revealed to us
		 * here), the simple name will be resolved to the non-'java.lang' class.
		 * Unless we simply force an import of *all* 'java.lang' classes.... :-(
		 * 
		 * This shouldn't happen very often. :-)
		 */
		protected static class ImportPackage {
			protected final String packageName;
			protected boolean collision = false;

			protected ImportPackage(String packageName) {
				super();
				this.packageName = packageName;
			}
		}

	}

}
