/*************************************************************************************
 * Copyright (c) 2012 Red Hat, Inc. and others.
 * 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:
 *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
 ************************************************************************************/
package org.eclipse.m2e.wtp.jpa.internal.configurators;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.apache.maven.project.MavenProject;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jpt.common.core.resource.ResourceLocator;
import org.eclipse.jpt.common.core.resource.xml.JptXmlResource;
import org.eclipse.jpt.jpa.core.JpaPlatform;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.JpaWorkspace;
import org.eclipse.jpt.jpa.core.internal.facet.JpaFacetDataModelProperties;
import org.eclipse.jpt.jpa.core.internal.facet.JpaFacetInstallDataModelProperties;
import org.eclipse.jpt.jpa.core.internal.facet.JpaFacetInstallDataModelProvider;
import org.eclipse.jpt.jpa.core.internal.resource.persistence.PersistenceXmlResourceProvider;
import org.eclipse.jpt.jpa.core.platform.JpaPlatformManager;
import org.eclipse.jpt.jpa.core.resource.persistence.XmlPersistenceUnit;
import org.eclipse.jst.common.project.facet.core.JavaFacet;
import org.eclipse.jst.common.project.facet.core.internal.JavaFacetUtil;
import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate;
import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderFramework;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
import org.eclipse.m2e.core.project.configurator.ILifecycleMappingConfiguration;
import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
import org.eclipse.m2e.wtp.MavenWtpPlugin;
import org.eclipse.m2e.wtp.ProjectUtils;
import org.eclipse.m2e.wtp.ResourceCleaner;
import org.eclipse.m2e.wtp.facets.FacetDetectorManager;
import org.eclipse.m2e.wtp.jpa.PlatformIdentifierManager;
import org.eclipse.m2e.wtp.jpa.internal.MavenJpaActivator;
import org.eclipse.m2e.wtp.jpa.internal.util.JptUtils;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetDataModelProperties;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;

/**
 * JPA Project configurator. Will install the JPA facet on a maven project containing a persistence.xml.
 *
 * @author Fred Bricon
 */
@SuppressWarnings("restriction")
public class JpaProjectConfigurator extends AbstractProjectConfigurator {

	private static final String JPA_NO_OP_LIBRARY_PROVIDER = "jpa-no-op-library-provider"; //$NON-NLS-1$
	
	private static final String M2E_JPA_ACTIVATION_PROPERTY = "m2e.jpa.activation"; //$NON-NLS-1$
	
	static final String PERSISTENCE_XML_KEY = "persistencexml";  //$NON-NLS-1$
	
	@Override
	public void configure(ProjectConfigurationRequest request,
			IProgressMonitor monitor) throws CoreException {
		IProject project = request.getProject();
		
		MavenProject mavenProject = request.getMavenProject();
		if(!canConfigure(project, mavenProject )) {
			return;
		}

		IFile persistenceXml = getPersistenceXml(project);
		if (persistenceXml == null || !persistenceXml.exists()) {
			//No persistence.xml => not a JPA project 
			return;
		}
		
		IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
		if (facetedProject != null) {
			//Refresh parent in multi-module setups, or Dali throws an exception 
			ProjectUtils.refreshHierarchy(request.getMavenProject().getBasedir(), 
										  IResource.DEPTH_INFINITE, 
										  new SubProgressMonitor(monitor, 1));
			
			//Configurators should *never* create files in the user's source folders
			ResourceCleaner cleaner = new ResourceCleaner(facetedProject.getProject());
			addFoldersToClean(cleaner, request.getMavenProjectFacade());
			try {
				configureFacets(facetedProject, request.getMavenProjectFacade(), persistenceXml, monitor);
			} finally {
				cleaner.cleanUp();
			}
		} 
	}

	private IFile getPersistenceXml(IProject project) {
		ResourceLocator resourceLocator = new MavenResourceLocator();
		
		IPath path = resourceLocator.getWorkspacePath(project, new Path("META-INF/persistence.xml")); //$NON-NLS-1$
		IFile persistenceXml = null;
		if (path != null) {
			persistenceXml = ResourcesPlugin.getWorkspace().getRoot().getFile(path);		
		}
		return persistenceXml;
	}

	private void configureFacets(IFacetedProject facetedProject, IMavenProjectFacade mavenProjectFacade, IFile persistenceXml, IProgressMonitor monitor)
			throws CoreException {
		
		//Need to refresh the persistence.xml as the resource provider might crash badly on some occasions
		//if it finds the file is out-of-sync
		persistenceXml.refreshLocal(IResource.DEPTH_ZERO, null);
		
		PersistenceXmlResourceProvider provider = PersistenceXmlResourceProvider.getXmlResourceProvider(persistenceXml);
		
		JptXmlResource jpaXmlResource = provider.getXmlResource(); 
		Map<?,?> context = Collections.singletonMap(PERSISTENCE_XML_KEY, jpaXmlResource);
		FacetDetectorManager facetDetectorManager = FacetDetectorManager.getInstance();
		
		IProjectFacetVersion version = facetDetectorManager.findFacetVersion(mavenProjectFacade, JpaProject.FACET.getId(), context, monitor);
		if (version == null) {
			return;
		}
		
		JpaPlatform.Config platform = getPlatform(jpaXmlResource, version);
		
		IDataModel dataModel = getDataModel(facetedProject, version, platform);

		Set<Action> actions = new LinkedHashSet<Action>();
		installJavaFacet(actions, facetedProject.getProject(), facetedProject);
		actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, 
								                version, 
								                dataModel));
		facetedProject.modify(actions, monitor);
	}

	
	private JpaPlatform.Config getPlatform(JptXmlResource persistenceXml, IProjectFacetVersion facetVersion) {
		XmlPersistenceUnit xmlPersistenceUnit = JptUtils.getFirstXmlPersistenceUnit(persistenceXml);
		if (xmlPersistenceUnit == null) {
			return null;
		}
		PlatformIdentifierManager identifierManager = MavenJpaActivator.getDefault().getPlatformIdentifierManager();
		String platformType = identifierManager.identify(xmlPersistenceUnit);
		JpaPlatformManager platformManager = getPlatformManager();
		if (platformType != null) {
			for (JpaPlatform.Config platform : platformManager.getJpaPlatformConfigs(facetVersion)) {
				if (platform.getId().contains(platformType)) {
					return platform;
				}
			}
		}
		//If no adequate platform found, Dali will use a default one.
		return null;
	}
	
	private JpaPlatformManager getPlatformManager() {
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		JpaWorkspace jpaWorkspace = (JpaWorkspace) workspace.getAdapter(JpaWorkspace.class);
		return jpaWorkspace.getJpaPlatformManager();
	}

	private IDataModel getDataModel(IFacetedProject facetedProject,
									IProjectFacetVersion version, 
									JpaPlatform.Config platformConfig) {
		
		IDataModel dm = DataModelFactory.createDataModel(new JpaFacetInstallDataModelProvider()); 

		dm.setProperty(IFacetDataModelProperties.FACET_VERSION_STR, version.getVersionString()); 
		dm.setProperty(JpaFacetDataModelProperties.PLATFORM, platformConfig); 
		//Gone in Kepler M7 dm.setProperty(JpaFacetInstallDataModelProperties.CREATE_ORM_XML, false);
		dm.setProperty(JpaFacetInstallDataModelProperties.DISCOVER_ANNOTATED_CLASSES, true);
		LibraryInstallDelegate libraryInstallDelegate = getNoOpLibraryProvider(facetedProject, version);
		dm.setProperty(JpaFacetInstallDataModelProperties.LIBRARY_PROVIDER_DELEGATE, libraryInstallDelegate);
		
		return dm;
	}

	private boolean canConfigure(IProject project, MavenProject mavenProject) throws CoreException {
		boolean enabled = isConfigurationEnabled(mavenProject);
		if (!enabled || !project.hasNature(JavaCore.NATURE_ID)) {
			return false;
		}
		// Bug 430178 : If imported project has modulecore nature without the component file, 
		// Dali's ModuleResourceLocator#getRootFolder will NPE (ex: it.cosenonjaviste:jsf2-spring4-jpa2-archetype:1.0.3)
		if (project.hasNature(IModuleConstants.MODULE_NATURE_ID) && !ModuleCoreNature.componentResourceExists(project)) {
			return false;
		}
		
		IFacetedProject fProj = ProjectFacetsManager.create(project);
		return  fProj == null || !fProj.hasProjectFacet(JpaProject.FACET);
	}

	private boolean isConfigurationEnabled(MavenProject mavenProject) {
		Object pomActivationValue = mavenProject.getProperties().get(M2E_JPA_ACTIVATION_PROPERTY);
		boolean enabled;
		if (pomActivationValue == null) {
			enabled = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().isEnabled(getId());
		} else {
			enabled = Boolean.parseBoolean(pomActivationValue.toString());
		}	
		return enabled;
	}
	
	private LibraryInstallDelegate getNoOpLibraryProvider(IFacetedProject facetedProject, IProjectFacetVersion facetVersion) {
		LibraryInstallDelegate libraryDelegate = new LibraryInstallDelegate(facetedProject, facetVersion);
		ILibraryProvider provider = LibraryProviderFramework.getProvider(JPA_NO_OP_LIBRARY_PROVIDER); 
		libraryDelegate.setLibraryProvider(provider);
		return libraryDelegate;
	}
	
	@Override
	public boolean hasConfigurationChanged(IMavenProjectFacade newFacade,
			ILifecycleMappingConfiguration oldProjectConfiguration,
			MojoExecutionKey key, IProgressMonitor monitor) {
		//Changes to maven-compiler-plugin in pom.xml don't make it "dirty" wrt JPA config
		return false;
	}
	
	private void installJavaFacet(Set<Action> actions, IProject project, IFacetedProject facetedProject) {
	    IProjectFacetVersion javaFv = JavaFacet.FACET.getVersion(JavaFacetUtil.getCompilerLevel(project));
	    if(!facetedProject.hasProjectFacet(JavaFacet.FACET)) {
	      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, javaFv, null));
	    } else if(!facetedProject.hasProjectFacet(javaFv)) {
	      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, javaFv, null));
	    } 
	}
	
	 protected void addFoldersToClean(ResourceCleaner fileCleaner, IMavenProjectFacade facade) {
		    for (IPath p : facade.getCompileSourceLocations()) {
		      if (p != null) {
		        fileCleaner.addFiles(p.append("META-INF/persistence.xml")); //$NON-NLS-1$
		        fileCleaner.addFiles(p.append("META-INF/orm.xml")); //$NON-NLS-1$
				fileCleaner.addFolder(p);
		      }
		    }
		    for (IPath p : facade.getResourceLocations()) {
		      if (p != null) {
			    fileCleaner.addFiles(p.append("META-INF/persistence.xml")); //$NON-NLS-1$
			    fileCleaner.addFiles(p.append("META-INF/orm.xml")); //$NON-NLS-1$
		        fileCleaner.addFolder(p);
		      }
		    }
		    for (IPath p : facade.getTestCompileSourceLocations()) {
		      if (p != null) {
				fileCleaner.addFolder(p);
			}
		    }
		    for (IPath p : facade.getTestResourceLocations()) {
		      if (p != null) {
				fileCleaner.addFolder(p);
			}
		    }
		  }
}
