/*******************************************************************************
 * 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.jpa.core.internal.jpa2;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

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.common.core.utility.BodySourceWriter;
import org.eclipse.jpt.common.utility.internal.ClassName;
import org.eclipse.jpt.common.utility.internal.SimpleStack;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.jpa.core.JptJpaCorePlugin;
import org.eclipse.jpt.jpa.core.context.AttributeMapping;
import org.eclipse.jpt.jpa.core.context.PersistentAttribute;
import org.eclipse.jpt.jpa.core.context.PersistentType;
import org.eclipse.jpt.jpa.core.jpa2.JpaProject2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.AttributeMapping2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.MetamodelField;
import org.eclipse.jpt.jpa.core.jpa2.context.MetamodelSourceType;
import org.eclipse.jpt.jpa.core.jpa2.resource.java.JPA2_0;
import org.eclipse.jpt.jpa.core.jpa2.resource.java.JavaResourcePersistentType2_0;

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 GenericMetamodelSynchronizer
	implements MetamodelSourceType.Synchronizer
{
	protected final MetamodelSourceType sourceType;


	public GenericMetamodelSynchronizer(MetamodelSourceType sourceType) {
		super();
		this.sourceType = sourceType;
	}

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


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

	public void synchronize(Map<String, Collection<MetamodelSourceType>> memberTypeTree) {
		try {
			this.synchronize_(memberTypeTree);
		} catch (JavaModelException ex) {
			JptJpaCorePlugin.log(ex);
		}
	}

	protected void synchronize_(Map<String, Collection<MetamodelSourceType>> memberTypeTree) 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, memberTypeTree);
			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(memberTypeTree), 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, Map<String, Collection<MetamodelSourceType>> memberTypeTree) throws JavaModelException {
		IFile file = (IFile) compilationUnit.getResource();
		JavaResourcePersistentType2_0 genType = this.getJpaProject().getGeneratedMetamodelTopLevelType(file);
		if (genType == null) {
			return null;  // the file exists, but its source is not a generated metamodel top-level class
		}

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

		String newSource = this.buildSource(memberTypeTree);
		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.sourceType.getJpaProject();
	}

	protected String getPackageName() {
		return this.buildPackageName(this.sourceType.getName());
	}

	protected String buildPackageName(String topLevelSourceTypeName) {
		return this.buildPackageName_(ClassName.getPackageName(topLevelSourceTypeName));
	}

	// TODO
	protected String buildPackageName_(String sourcePackageName) {
		// the default is to store the metamodel class in the same package as the source type
		return sourcePackageName;
	}

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

	protected String getClassName() {
		return this.buildClassName(this.sourceType.getName());
	}

	protected String buildClassName(Map<String, Collection<MetamodelSourceType>> memberTypeTree) {
		return this.buildClassName(this.sourceType.getName(), memberTypeTree);
	}

	protected String buildClassName(String sourceTypeName, Map<String, Collection<MetamodelSourceType>> memberTypeTree) {
		String current = sourceTypeName;
		SimpleStack<String> stack = new SimpleStack<String>();

		while (true) {
			stack.push(ClassName.getSimpleName(current));
			String declaringTypeName = this.getDeclaringTypeName(current, memberTypeTree);
			if (declaringTypeName == null) {
				break;
			}
			current = declaringTypeName;
		}

		StringBuilder sb = new StringBuilder(sourceTypeName.length() + 10);
		sb.append(this.buildPackageName(current));
		while ( ! stack.isEmpty()) {
			sb.append('.');
			sb.append(this.buildSimpleClassName(stack.pop()));
		}
		return sb.toString();
	}

	protected String buildClassName(String topLevelSourceTypeName) {
		return this.buildPackageName(topLevelSourceTypeName) + '.' + this.buildSimpleClassName(ClassName.getSimpleName(topLevelSourceTypeName));
	}

	protected String getSimpleClassName() {
		return this.buildSimpleClassName(ClassName.getSimpleName(this.sourceType.getName()));
	}

	// TODO
	protected String buildSimpleClassName(String simpleSourceTypeName) {
		// the default is to simply append an underscore to the source type name
		return simpleSourceTypeName + '_';
	}


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

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

		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(Map<String, Collection<MetamodelSourceType>> memberTypeTree) {
		BodySourceWriter pw = new BodySourceWriter(this.getPackageName(), this.getClassName());
		this.printBodySourceOn(pw, memberTypeTree);
		return pw;
	}

	public void printBodySourceOn(BodySourceWriter pw, Map<String, Collection<MetamodelSourceType>> memberTypeTree) {
		this.printClassDeclarationOn(pw, memberTypeTree);
		pw.print(" {");
		pw.println();

		pw.indent();
			boolean attributesPrinted = this.printAttributesOn(pw);
			this.printMemberTypesOn(pw, memberTypeTree, attributesPrinted);
		pw.undent();

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


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

	protected void printClassDeclarationOn(BodySourceWriter pw, Map<String, Collection<MetamodelSourceType>> memberTypeTree) {
		boolean topLevel = this.sourceTypeIsTopLevel(memberTypeTree);
		if (topLevel) {
			this.printGeneratedAnnotationOn(pw);
		}
		if (this.sourceType.isManaged()) {
			this.printStaticMetamodelAnnotationOn(pw);
		}

		pw.print("public ");
		if ( ! topLevel) {
			pw.print("static ");
		}
		pw.print("class ");
		pw.print(this.getSimpleClassName());  // this is always the simple name
		PersistentType superPersistentType = this.sourceType.getSuperPersistentType();
		if (superPersistentType != null) {
			pw.print(" extends ");
			pw.printTypeDeclaration(this.buildClassName(superPersistentType.getName(), memberTypeTree));
		}
	}

	/**
	 * Return whether the source type is a top level type.
	 * This can be inferred from the specified member type tree.
	 */
	protected boolean sourceTypeIsTopLevel(Map<String, Collection<MetamodelSourceType>> memberTypeTree) {
		return this.sourceTypeIsTopLevel(this.sourceType.getName(), memberTypeTree);
	}

	/**
	 * Return whether the specified source type is a top level type.
	 * This can be inferred from the specified member type tree.
	 */
	protected boolean sourceTypeIsTopLevel(String sourceTypeName, Map<String, Collection<MetamodelSourceType>> memberTypeTree) {
		return this.getDeclaringTypeName(sourceTypeName, memberTypeTree) == null;
	}

	/**
	 * Return the name of the specified source type's declaring type, as
	 * implied by the specified member type tree. Return null if the source
	 * type is a top-level type.
	 */
	protected String getDeclaringTypeName(String sourceTypeName, Map<String, Collection<MetamodelSourceType>> memberTypeTree) {
		int lastPeriod = sourceTypeName.lastIndexOf('.');
		if (lastPeriod == -1) {
			return null;  // default package top-level type
		}
		String declaringTypeName = sourceTypeName.substring(0, lastPeriod);
		return (memberTypeTree.get(declaringTypeName) == null) ? null : declaringTypeName;
	}

	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();
	}

	protected void printStaticMetamodelAnnotationOn(BodySourceWriter pw) {
		pw.printAnnotation(JPA2_0.STATIC_METAMODEL);
		pw.print('(');
		pw.printTypeDeclaration(this.sourceType.getName());
		pw.print(".class");
		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 **********

	/**
	 * Return whether any attributes were printed.
	 */
	protected boolean printAttributesOn(BodySourceWriter pw) {
		boolean printed = false;
		for (Iterator<PersistentAttribute> stream = this.sourceType.attributes(); stream.hasNext(); ) {
			this.printAttributeOn(stream.next(), pw);
			printed = true;
		}
		return printed;
	}

	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();
	}


	// ********** member types **********

	protected void printMemberTypesOn(BodySourceWriter pw, Map<String, Collection<MetamodelSourceType>> memberTypeTree, boolean attributesPrinted) {
		Collection<MetamodelSourceType> memberTypes = memberTypeTree.get(this.sourceType.getName());
		if (memberTypes != null) {
			if (attributesPrinted) {
				pw.println();
			}
			for (Iterator<MetamodelSourceType> stream = memberTypes.iterator(); stream.hasNext(); ) {
				stream.next().printBodySourceOn(pw, memberTypeTree);
				if (stream.hasNext()) {
					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();
	}


	// ********** misc **********

	@Override
	public String toString() {
		return StringTools.buildToStringFor(this, this.sourceType.getName());
	}

}
