/*************************************************************************************
 * Copyright (c) 2012-2015 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 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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.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.WTPProjectsUtil;
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 {

		if(!canConfigure(request.getMavenProjectFacade(), monitor)) {
			return;
		}
		IProject project = request.getProject();
		MavenProject mavenProject = request.getMavenProject();

		IFile persistenceXml = getPersistenceXml(request.getMavenProjectFacade());
		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(mavenProject.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(IMavenProjectFacade mavenProjectFacade) {
		MavenResourceLocator resourceLocator = new MavenResourceLocator();
		IPath path = resourceLocator.lookupMavenResources(mavenProjectFacade, 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<>();
		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(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
		if (!WTPProjectsUtil.isLastConfigurator(facade, getClass(), getId())) {
			return false;
		}
		boolean enabled = isConfigurationEnabled(facade, monitor);
		if (!enabled) {
			return false;
		}
		IProject project = facade.getProject();
		// 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(JavaCore.NATURE_ID) ||
				(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(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
		if (WTPProjectsUtil.isM2eWtpDisabled(facade, monitor)) {
			return false;
		}

		Object pomActivationValue = facade.getMavenProject(monitor).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);
			}
		    }
		  }
}
