/*******************************************************************************
 * Copyright (c) 2009 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.ClassTools;
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 ClassTools.packageNameForClassNamed(this.getMetamodelClassName());
	}

	protected String getFileName() {
		return ClassTools.shortNameForClassNamed(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>, 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;
			}
		}

	}

}
