/*******************************************************************************
 * Copyright (c) 2009, 2011 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.context.persistence;

import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jpt.common.core.resource.java.JavaResourcePackageFragmentRoot;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable;
import org.eclipse.jpt.jpa.core.JpaFile;
import org.eclipse.jpt.jpa.core.JpaStructureNode;
import org.eclipse.jpt.jpa.core.JptJpaCorePlugin;
import org.eclipse.jpt.jpa.core.context.PersistentType;
import org.eclipse.jpt.jpa.core.context.java.JarFile;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType;
import org.eclipse.jpt.jpa.core.context.persistence.JarFileRef;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceStructureNodes;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages;
import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages;
import org.eclipse.jpt.jpa.core.resource.persistence.XmlJarFileRef;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;

/**
 * <code>persistence.xml</code> file
 * <br>
 * <code>jar-file</code> element
 */
public abstract class AbstractJarFileRef
	extends AbstractPersistenceXmlContextNode
	implements JarFileRef
{
	protected final XmlJarFileRef xmlJarFileRef;

	protected String fileName;

	/**
	 * the jar file corresponding to the ref's file name;
	 * this can be null if the name is invalid
	 */
	protected JarFile jarFile;


	// ********** construction/initialization **********

	public AbstractJarFileRef(PersistenceUnit parent, XmlJarFileRef xmlJarFileRef) {
		super(parent);
		this.xmlJarFileRef = xmlJarFileRef;
		this.fileName = xmlJarFileRef.getFileName();
		this.jarFile = this.buildJarFile();
	}


	// ********** synchronize/update **********

	@Override
	public void synchronizeWithResourceModel() {
		super.synchronizeWithResourceModel();
		this.setFileName_(this.xmlJarFileRef.getFileName());
		this.syncJarFile();
	}

	@Override
	public void update() {
		super.update();
		this.updateJarFile();
	}


	// ********** JpaStructureNode implementation **********

	public String getId() {
		return PersistenceStructureNodes.JAR_FILE_REF_ID;
	}

	public JpaStructureNode getStructureNode(int textOffset) {
		return this;
	}

	public TextRange getSelectionTextRange() {
		return (this.xmlJarFileRef == null) ? null : this.xmlJarFileRef.getSelectionTextRange();
	}

	public void dispose() {
		if (this.jarFile != null) {
			this.jarFile.dispose();
		}
	}


	// ********** file name **********

	public String getFileName() {
		return this.fileName;
	}

	public void setFileName(String fileName) {
		this.setFileName_(fileName);
		this.xmlJarFileRef.setFileName(fileName);
	}

	/**
	 * We clear out {@link #jarFile} here because we cannot compare its file
	 * name to the ref's file name, since it may have been munged (see
	 * {@link #resolveJavaResourcePackageFragmentRoot_()}).
	 */
	protected void setFileName_(String fileName) {
		String old = this.fileName;
		this.fileName = fileName;
		if (this.firePropertyChanged(FILE_NAME_PROPERTY, old, fileName)) {
			// clear out the jar file here, it will be rebuilt during "update"
			if (this.jarFile != null) {
				this.jarFile.dispose();
				this.setJarFile(null);
			}
		}
	}


	// ********** jar file **********

	public JarFile getJarFile() {
		return this.jarFile;
	}

	protected void setJarFile(JarFile jarFile) {
		JarFile old = this.jarFile;
		this.jarFile = jarFile;
		this.firePropertyChanged(JAR_FILE_PROPERTY, old, jarFile);
	}

	protected JarFile buildJarFile() {
		JavaResourcePackageFragmentRoot jrpfr = this.resolveJavaResourcePackageFragmentRoot();
		return (jrpfr == null) ? null : this.buildJarFile(jrpfr);
	}

	/**
	 * If the file name changes during <em>sync</em>, the jar file will be
	 * cleared out in {@link #setFileName_(String)}. If we get here and the jar
	 * file is still present, we can <code>sync</code> it. Of course, it might
	 * still be obsolete if other things have changed....
	 * 
	 * @see #updateJarFile()
	 */
	protected void syncJarFile() {
		if (this.jarFile != null) {
			this.jarFile.synchronizeWithResourceModel();
		}
	}

	/**
	 * @see #syncJarFile()
	 */
	protected void updateJarFile() {
		JavaResourcePackageFragmentRoot jrpfr = this.resolveJavaResourcePackageFragmentRoot();
		if (jrpfr == null) {
			if (this.jarFile != null) {
				this.jarFile.dispose();
				this.setJarFile(null);
			}
		} else {
			if (this.jarFile == null) {
				this.setJarFile(this.buildJarFile(jrpfr));
			} else {
				if (this.jarFile.getJarResourcePackageFragmentRoot() == jrpfr) {
					this.jarFile.update();
				} else {
					this.jarFile.dispose();
					this.setJarFile(this.buildJarFile(jrpfr));
				}
			}
		}
	}

	protected JavaResourcePackageFragmentRoot resolveJavaResourcePackageFragmentRoot() {
		return StringTools.stringIsEmpty(this.fileName) ? null : this.resolveJavaResourcePackageFragmentRoot_();
	}

	/**
	 * pre-condition: 'fileName' is neither null nor empty
	 */
	protected JavaResourcePackageFragmentRoot resolveJavaResourcePackageFragmentRoot_() {
		// first, attempt to resolve location specifically...
		JavaResourcePackageFragmentRoot jrpfr = this.resolveJrpfrOnDeploymentPath();
		// ...then guess, basically
		return (jrpfr != null) ? jrpfr : this.resolveJrpfrBestMatch();
	}

	/**
	 * pre-condition: 'fileName' is neither null nor empty
	 */
	protected JavaResourcePackageFragmentRoot resolveJrpfrOnDeploymentPath() {
		for (IPath runtimePath : this.buildRuntimeJarFilePath(new Path(this.fileName))) {
			IVirtualFile virtualJar = ComponentCore.createFile(this.getProject(), runtimePath);
			IFile realJar = virtualJar.getUnderlyingFile();
			if (realJar.exists() && realJar.getProject().equals(this.getProject())) {
				return this.getJpaProject().getJavaResourcePackageFragmentRoot(realJar.getProjectRelativePath().toString());
			}
		}
		return null;
	}

	/**
	 * Return an array of runtime paths that may correspond
	 * to the given persistence.xml jar file entry
	 */
	protected IPath[] buildRuntimeJarFilePath(IPath jarFilePath) {
		IPath root = this.getJarRuntimeRootPath();
		return this.projectHasWebFacet() ?
				this.buildRuntimeJarFilePathWeb(root, jarFilePath) :
				this.buildRuntimeJarFilePathNonWeb(root, jarFilePath);
	}

	protected IPath getJarRuntimeRootPath() {
		return JptJpaCorePlugin.getJarRuntimeRootPath(this.getProject());
	}

	protected boolean projectHasWebFacet() {
		return JptJpaCorePlugin.projectHasWebFacet(this.getProject());
	}

	protected IPath[] buildRuntimeJarFilePathWeb(IPath root, IPath jarFilePath) {
		return new IPath[] {
				// first path entry assumes form "../lib/other.jar"
				root.append(jarFilePath.removeFirstSegments(1)),
				// second path entry assumes form of first, without ".." ("lib/other.jar")
				root.append(jarFilePath)
			};
	}

	protected IPath[] buildRuntimeJarFilePathNonWeb(IPath root, IPath jarFilePath) {
		return new IPath[] {
				// assumes form "../lib/other.jar"
				root.append(jarFilePath)
			};
	}

	protected IProject getProject() {
		return this.getJpaProject().getProject();
	}

	/**
	 * pre-condition: 'fileName' is neither null nor empty
	 */
	protected JavaResourcePackageFragmentRoot resolveJrpfrBestMatch() {
		String jarFileName = new Path(this.fileName).lastSegment();
		for (JpaFile jpaFile : this.getJpaProject().getJarJpaFiles()) {
			if (jpaFile.getFile().getName().equals(jarFileName)) {
				return (JavaResourcePackageFragmentRoot) jpaFile.getResourceModel();
			}
		}
		return null;
	}

	/**
	 * pre-condition: 'jrpfr' is not null
	 */
	protected JarFile buildJarFile(JavaResourcePackageFragmentRoot jrpfr) {
		return this.getContextNodeFactory().buildJarFile(this, jrpfr);
	}


	// ********** JarFileRef implementation **********

	public XmlJarFileRef getXmlJarFileRef() {
		return this.xmlJarFileRef;
	}

	public PersistentType getPersistentType(String typeName) {
		return (this.jarFile == null) ? null : this.jarFile.getPersistentType(typeName);
	}

	public boolean containsOffset(int textOffset) {
		return (this.xmlJarFileRef != null) && this.xmlJarFileRef.containsOffset(textOffset);
	}


	// ********** PersistentTypeContainer implementation **********

	public Iterable<? extends PersistentType> getPersistentTypes() {
		return (this.jarFile != null) ? this.jarFile.getPersistentTypes() : EmptyIterable.<JavaPersistentType>instance();
	}


	// ********** XmlContextNode implementation **********

	public TextRange getValidationTextRange() {
		TextRange textRange = this.getXmlJarFileRefTextRange();
		return (textRange != null) ? textRange : this.getPersistenceUnit().getValidationTextRange();
	}

	protected TextRange getXmlJarFileRefTextRange() {
		return (this.xmlJarFileRef == null) ? null : this.xmlJarFileRef.getValidationTextRange();
	}


	// ********** refactoring **********

	public Iterable<ReplaceEdit> createReplaceFolderEdits(IFolder originalFolder, String newName) {
		return this.isIn(originalFolder) ?
				new SingleElementIterable<ReplaceEdit>(this.createReplaceFolderEdit(originalFolder, newName)) :
				EmptyIterable.<ReplaceEdit>instance();
	}

	protected ReplaceEdit createReplaceFolderEdit(IFolder originalFolder, String newName) {
		return this.xmlJarFileRef.createReplaceFolderEdit(originalFolder, newName);
	}

	protected boolean isIn(IFolder folder) {
		return (this.jarFile != null) && this.jarFile.isIn(folder);
	}


	// ********** validation **********

	@Override
	public void validate(List<IMessage> messages, IReporter reporter) {
		super.validate(messages, reporter);

		if (StringTools.stringIsEmpty(this.xmlJarFileRef.getFileName())) {
			messages.add(
				DefaultJpaValidationMessages.buildMessage(
					IMessage.HIGH_SEVERITY,
					JpaValidationMessages.PERSISTENCE_UNIT_UNSPECIFIED_JAR_FILE,
					this,
					this.getValidationTextRange()
				)
			);
			return;
		}

		messages.add(
			DefaultJpaValidationMessages.buildMessage(
				IMessage.NORMAL_SEVERITY,
				JpaValidationMessages.PERSISTENCE_UNIT_JAR_FILE_DEPLOYMENT_PATH_WARNING,
				this,
				this.getValidationTextRange()
			)
		);

		if (this.jarFile == null) {
			messages.add(
				DefaultJpaValidationMessages.buildMessage(
					IMessage.HIGH_SEVERITY,
					JpaValidationMessages.PERSISTENCE_UNIT_NONEXISTENT_JAR_FILE,
					new String[] {this.xmlJarFileRef.getFileName()},
					this,
					this.getValidationTextRange()
				)
			);
			return;
		}

		this.jarFile.validate(messages, reporter);
	}


	// ********** overrides **********

	@Override
	public PersistenceUnit getParent() {
		return (PersistenceUnit) super.getParent();
	}

	@Override
	public void toString(StringBuilder sb) {
		super.toString(sb);
		sb.append(this.fileName);
	}

}
