/*******************************************************************************
 * Copyright (c) 2006, 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.core.internal.platform;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Path;
import org.eclipse.jpt.core.internal.IJpaCoreConstants;
import org.eclipse.jpt.core.internal.IJpaFile;
import org.eclipse.jpt.core.internal.IJpaPlatform;
import org.eclipse.jpt.core.internal.IJpaProject;
import org.eclipse.jpt.core.internal.IMappingKeys;
import org.eclipse.jpt.core.internal.IPersistentType;
import org.eclipse.jpt.core.internal.JptCorePlugin;
import org.eclipse.jpt.core.internal.content.java.JavaPersistentType;
import org.eclipse.jpt.core.internal.content.java.JpaCompilationUnit;
import org.eclipse.jpt.core.internal.content.persistence.Persistence;
import org.eclipse.jpt.core.internal.content.persistence.PersistenceUnit;
import org.eclipse.jpt.core.internal.content.persistence.PersistenceXmlRootContentNode;
import org.eclipse.jpt.core.internal.validation.IJpaValidationMessages;
import org.eclipse.jpt.core.internal.validation.JpaValidationMessages;
import org.eclipse.jpt.db.internal.Connection;
import org.eclipse.jpt.db.internal.ConnectionProfile;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;

/**
 * The jpaProject context used for base jpa projects.  It is assumed that
 * the jpaProject contains at least 1 persistence.xml file.  Multiple persistence.xml
 * files will be treated as an error condition, no defaults or validation based
 * on the context of a persistence-unit will be given. Currently no support for default orm.xml
 * files or defaulting annotated java files, we don't know how the information will be packaged.
 * 
 * Multiple persistence-units can be supported, but the resulting defaults/validation
 * may be incorrect.  If the persistence-units have overlap in the java files they specify
 * as mapped, then the defaults could be wrong depending on the context.  We can only use 1 set 
 * of defaults in our tooling.
 */
public class BaseJpaProjectContext extends BaseContext
{	
	private IJpaProject jpaProject;

	private List<IJpaFile> validPersistenceXmlFiles;
	private List<IJpaFile> invalidPersistenceXmlFiles;
	
	private Collection<PersistenceUnitContext> persistenceUnitContexts;

	public BaseJpaProjectContext(IJpaProject theJpaProject) {
		super(null);
		jpaProject = theJpaProject;
		validPersistenceXmlFiles = new ArrayList<IJpaFile>();
		invalidPersistenceXmlFiles = new ArrayList<IJpaFile>();
		persistenceUnitContexts = new ArrayList<PersistenceUnitContext>();
	}
	
	@Override
	protected void initialize() {
		sortPersistenceXmlFiles();
		buildPersistenceUnitContexts();
	}
	
	private void sortPersistenceXmlFiles() {
		for (IJpaFile jpaFile : persistenceXmlFiles()) {
			if (isValidPersistenceXmlLocation(jpaFile)) {
				validPersistenceXmlFiles.add(jpaFile);
			}
			else {
				invalidPersistenceXmlFiles.add(jpaFile);
			}
		}
	}
	
	private Collection<IJpaFile> persistenceXmlFiles() {
		return this.jpaProject.jpaFiles(JptCorePlugin.PERSISTENCE_XML_CONTENT_TYPE);
	}
	
	private boolean isValidPersistenceXmlLocation(IJpaFile jpaFile) {
		IFile file = jpaFile.getFile();
		IProject project = jpaProject.getProject();
		
		// check flexible jpaProject structure
		IVirtualComponent component = ComponentCore.createComponent(project);
		IVirtualFolder rootFolder = component.getRootFolder();
		IVirtualFolder metaInfFolder = rootFolder.getFolder(new Path(IJpaCoreConstants.META_INF));
		return metaInfFolder.exists() && CollectionTools.contains(metaInfFolder.getUnderlyingFolders(), file.getParent());
	}

	//TODO need to handle clearing out defaults for JpaFiles that aren't in a persistenceUnit
	// or for when there are multiple persistence.xml files
	//TODO how do we handle files being in multiple persistenceUnits?  this is valid, but
	//our tool can really only show defaults for one or the other. should clear out defaults and
	//probably have a warning letting the user know why they get no defaults or validation
	protected void buildPersistenceUnitContexts() {
		// we currently only support *one* persistence.xml file per jpaProject,
		// so we provide no defaults or validation for those that have more or less
		if (validPersistenceXmlFiles.size() == 1) {
			IJpaFile file = validPersistenceXmlFiles.get(0);
			buildPersistenceUnitContexts(getPersistence(file));
		}
	}
	
	protected void buildPersistenceUnitContexts(Persistence persistence) {
		if (persistence != null) {
			for (Iterator stream = persistence.getPersistenceUnits().iterator(); stream.hasNext();) {
				PersistenceUnit persistenceUnit = (PersistenceUnit) stream.next();
				PersistenceUnitContext persistenceUnitContext = new PersistenceUnitContext(this, persistenceUnit);
				persistenceUnitContexts.add(persistenceUnitContext);
			}
		}
	}
	
	protected Persistence getPersistence(IJpaFile persistenceXmlFile) {
		return ((PersistenceXmlRootContentNode) persistenceXmlFile.getContent()).getPersistence();
	}
	
	@Override
	public IJpaPlatform getPlatform() {
		return this.jpaProject.getPlatform();
	}
	
	protected Iterator<IJpaFile> validPersistenceXmlFiles(){
		return validPersistenceXmlFiles.iterator();
	}
	
	public void refreshDefaults() {
		refreshDefaults(null);
	}
	
	public void refreshDefaults(DefaultsContext parentDefaults) {
		super.refreshDefaults(parentDefaults);
		DefaultsContext defaultsContext = buildDefaultsContext();
		for (PersistenceUnitContext context : this.persistenceUnitContexts) {
			context.refreshDefaults(defaultsContext);
		}
	}
	
	private DefaultsContext buildDefaultsContext() {
		return new DefaultsContext(){
			public Object getDefault(String key) {
				if (key.equals(BaseJpaPlatform.DEFAULT_TABLE_SCHEMA_KEY) 
					|| key.equals(BaseJpaPlatform.DEFAULT_TABLE_GENERATOR_SCHEMA_KEY)) {
					return getProjectUserSchema();
				}
				else if (key.equals(BaseJpaPlatform.DEFAULT_TABLE_CATALOG_KEY)) {
					return getProjectUserCatalog();
				}
				return null;
			}
			public IPersistentType persistentType(String fullyQualifiedTypeName) {
				return null;
			}
		};
	}
	
	protected ConnectionProfile getProjectConnectionProfile() {
		return this.jpaProject.connectionProfile();
	}
	
	//TODO is the userName what we want to use, or do we need a preference for the user?
	private String getProjectUserSchema() {
		ConnectionProfile profile = this.getProjectConnectionProfile();
		return  profile.getUserName();
	}

	private String getProjectUserCatalog() {
		ConnectionProfile profile = this.getProjectConnectionProfile();
		return profile.getCatalogName();
	}
	
	public boolean contains(IPersistentType persistentType) {
		for (PersistenceUnitContext context : this.persistenceUnitContexts) {
			if (context.contains(persistentType)) {
				return true;
			}
		}
		return false;
	}

	private Iterator<PersistenceUnitContext> persistenceUnitContexts() {
		return this.persistenceUnitContexts.iterator();
	}
	
	int persistenceUnitContextsSize() {
		return this.persistenceUnitContexts.size();
	}

	PersistenceUnitContext persistenceUnitContext(String persistenceUnitName) {
		for (Iterator<PersistenceUnitContext> stream = persistenceUnitContexts(); stream.hasNext(); ) {
			PersistenceUnitContext puContext = stream.next();
			if (puContext.persistenceUnit().getName().equals(persistenceUnitName)) {
				return puContext;
			}
		}
		return null;
	}
	
	Iterator<PersistenceUnit> persistenceUnits() {
		return new TransformationIterator<PersistenceUnitContext, PersistenceUnit>(this.persistenceUnitContexts()) {
			@Override
			protected PersistenceUnit transform(PersistenceUnitContext next) {
				 return next.persistenceUnit();
			}
		};
	}

	public boolean containsPersistenceUnitNamed(String name) {
		return this.persistenceUnitNamed(name) != null;
	}

	PersistenceUnit persistenceUnitNamed(String name) {
		for (PersistenceUnitContext context : this.persistenceUnitContexts) {
			if( context.persistenceUnit().getName().equals(name)) {
				return context.persistenceUnit();
			}
		}
		return null;
	}
		
//	public IGeneratorRepository generatorRepository(IPersistentType persistentType) {
//		for (PersistenceUnitContext context : this.persistenceUnitContexts) {
//			if (context.contains(persistentType)) {
//				context.getGeneratorRepository();
//			}
//		}
//		return NullGeneratorRepository.instance();
//	}
	
	/* If this is true, it may be assumed that all the requirements are valid 
	 * for further validation.  For example, if this is true at the point we
	 * are validating persistence units, it may be assumed that there is a 
	 * single persistence.xml and that it has valid content down to the 
	 * persistence unit level.  */
	private boolean okToContinueValidation = true;
	
	public void addToMessages(List<IMessage> messages) {
		super.addToMessages(messages);
		addProjectLevelMessages(messages);
		if (okToContinueValidation) {
			for (PersistenceUnitContext context : persistenceUnitContexts) {
				context.addToMessages(messages);
			}
		}
		addOrphanedJavaClassMessages(messages);
	}
	
	protected void addProjectLevelMessages(List<IMessage> messages) {
		addConnectionMessages(messages);
		addNoPersistenceXmlMessage(messages);
		addMultiplePersistenceXmlMessage(messages);
		addInvalidPersistenceXmlContentMessage(messages);
		addNoPersistenceUnitMessage(messages);
		addMultiplePersistenceUnitMessage(messages);
	}
	
	protected void addConnectionMessages(List<IMessage> messages) {
		addNoConnectionMessage(messages);
		addInactiveConnectionMessage(messages);
	}
	
	protected boolean okToProceedForConnectionValidation = true;
	
	protected void addNoConnectionMessage(List<IMessage> messages) {
		Connection connection = jpaProject.getDataSource().getConnection();
		if (connection == null) {
			messages.add(
					JpaValidationMessages.buildMessage(
						IMessage.NORMAL_SEVERITY,
						IJpaValidationMessages.PROJECT_NO_CONNECTION,
						jpaProject)
				);
			okToProceedForConnectionValidation = false;
		}
	}
	
	protected void addInactiveConnectionMessage(List<IMessage> messages) {
		Connection connection = jpaProject.getDataSource().getConnection();
		if (okToProceedForConnectionValidation && ! connection.isConnected()) {
			messages.add(
					JpaValidationMessages.buildMessage(
						IMessage.NORMAL_SEVERITY,
						IJpaValidationMessages.PROJECT_INACTIVE_CONNECTION,
						new String[] {jpaProject.getDataSource().getConnectionProfileName()},
						jpaProject)
				);
		}
		okToProceedForConnectionValidation = true;
	}
	
	protected void addNoPersistenceXmlMessage(List<IMessage> messages) {
		if (validPersistenceXmlFiles.isEmpty()) {
			messages.add(
					JpaValidationMessages.buildMessage(
						IMessage.HIGH_SEVERITY, 
						IJpaValidationMessages.PROJECT_NO_PERSISTENCE_XML,
						jpaProject)
				);
			okToContinueValidation = false;
		}
	}
	
	protected void addMultiplePersistenceXmlMessage(List<IMessage> messages) {
		if (validPersistenceXmlFiles.size() > 1) {
			messages.add(
					JpaValidationMessages.buildMessage(
						IMessage.HIGH_SEVERITY,
						IJpaValidationMessages.PROJECT_MULTIPLE_PERSISTENCE_XML,
						jpaProject)
				);
			okToContinueValidation = false;
		}
	}
	
	protected void addInvalidPersistenceXmlContentMessage(List<IMessage> messages) {
		if (validPersistenceXmlFiles.size() == 1) {
			IJpaFile persistenceXmlFile = (IJpaFile) validPersistenceXmlFiles.get(0);
			if (getPersistence(persistenceXmlFile) == null) {
				PersistenceXmlRootContentNode root = 
					(PersistenceXmlRootContentNode) persistenceXmlFile.getContent();
				messages.add(
						JpaValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							IJpaValidationMessages.PERSISTENCE_XML_INVALID_CONTENT,
							root, root.validationTextRange())
					);
				okToContinueValidation = false;
			}
		}
	}
	
	protected void addNoPersistenceUnitMessage(List<IMessage> messages) {
		if (okToContinueValidation && persistenceUnitContexts.size() == 0) {
			IJpaFile validPersistenceXml = validPersistenceXmlFiles.get(0);
			Persistence persistence = getPersistence(validPersistenceXml);
			messages.add(
					JpaValidationMessages.buildMessage(
						IMessage.HIGH_SEVERITY,
						IJpaValidationMessages.PERSISTENCE_NO_PERSISTENCE_UNIT,
						persistence, persistence.validationTextRange())
				);
			okToContinueValidation = false;
		}
	}
	
	protected void addMultiplePersistenceUnitMessage(List<IMessage> messages) {
		if (okToContinueValidation && persistenceUnitContexts.size() > 1) {
			IJpaFile validPersistenceXml = validPersistenceXmlFiles.get(0);
			Persistence persistence = getPersistence(validPersistenceXml);
			messages.add(
					JpaValidationMessages.buildMessage(
						IMessage.HIGH_SEVERITY,
						IJpaValidationMessages.PERSISTENCE_MULTIPLE_PERSISTENCE_UNITS,
						persistence, persistence.validationTextRange())
				);
			okToContinueValidation = false;
		}
	}
	
	protected void addOrphanedJavaClassMessages(List<IMessage> messages) {
		for (IJpaFile jpaFile : jpaProject.jpaFiles(JptCorePlugin.JAVA_CONTENT_TYPE)) {
			for (JavaPersistentType jpType : ((JpaCompilationUnit) jpaFile.getContent()).getTypes()) {
				if (jpType.getMappingKey() != IMappingKeys.NULL_TYPE_MAPPING_KEY && ! contains(jpType)) {
					messages.add(
							JpaValidationMessages.buildMessage(
								IMessage.HIGH_SEVERITY,
								IJpaValidationMessages.PERSISTENT_TYPE_UNSPECIFIED_CONTEXT,
								jpType.getMapping(), jpType.getMapping().validationTextRange())
						);
				}
			}
		}
	}
	
	public String toString() {
		return StringTools.buildToStringFor( this, this.jpaProject.getJavaProject().getProject().getName());
	}	
}
