
/*******************************************************************************
 * Copyright (c) 2008 Sonatype, Inc.
 * 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
 *******************************************************************************/

package org.eclipse.m2e.wtp;

import static org.eclipse.m2e.wtp.WTPProjectsUtil.removeConflictingFacets;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.StringUtils;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
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.jdt.core.JavaCore;
import org.eclipse.jst.j2ee.earcreation.IEarFacetInstallDataModelProperties;
import org.eclipse.jst.j2ee.internal.earcreation.EarFacetInstallDataModelProvider;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.model.IEARModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.javaee.application.Application;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.wtp.earmodules.EarModule;
import org.eclipse.m2e.wtp.internal.Messages;
import org.eclipse.m2e.wtp.internal.utilities.PathUtil;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Configures EAR projects based on their maven-ear-plugin configuration.
 * 
 * @see org.eclipse.jst.j2ee.ui.AddModulestoEARPropertiesPage
 * @author Fred Bricon
 */
@SuppressWarnings("restriction")
class EarProjectConfiguratorDelegate extends AbstractProjectConfiguratorDelegate {

  private static final Logger LOG = LoggerFactory.getLogger(EarProjectConfiguratorDelegate.class); 

  @Override
protected void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
      throws CoreException {
    
    monitor.setTaskName(NLS.bind(Messages.EarProjectConfiguratorDelegate_Configuring_EAR_Project,project.getName()));
    
    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
    IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().create(project.getFile(IMavenConstants.POM_FILE_NAME), true, monitor);
    
    EarPluginConfiguration config = new EarPluginConfiguration(mavenProject);
    Set<Action> actions = new LinkedHashSet<>();

    String contentDir = config.getEarContentDirectory(project);
    contentDir = PathUtil.toPortablePath(contentDir);
    IFolder contentFolder = project.getFolder(contentDir);

    ResourceCleaner fileCleaner = new ResourceCleaner(project);
    addFoldersToClean(fileCleaner, facade);
    fileCleaner.addFiles(contentFolder.getFile("META-INF/application.xml").getProjectRelativePath()); //$NON-NLS-1$

    IProjectFacetVersion earFv = config.getEarFacetVersion();
    if(!facetedProject.hasProjectFacet(WTPProjectsUtil.EAR_FACET)) {
      removeConflictingFacets(facetedProject, earFv, actions);
      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, earFv, getEarModel(contentDir)));
    } else {
      //MECLIPSEWTP-37 : don't uninstall the EAR Facet, as it causes constraint failures when used with RAD
      IProjectFacetVersion projectFacetVersion = facetedProject.getProjectFacetVersion(WTPProjectsUtil.EAR_FACET);     
      if(earFv.getVersionString() != null && !earFv.getVersionString().equals(projectFacetVersion.getVersionString())){
          actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, earFv, getEarModel(contentDir)));
      } 
    }
    
    try {
      if(!actions.isEmpty()) {
        facetedProject.modify(actions, monitor);
      }
    }
    finally {
      try {
        //Remove any WTP created files (extra application.xml and manifest) 
        fileCleaner.cleanUp();
      } catch (CoreException cex) {
        LOG.error(Messages.Error_Cleaning_WTP_Files, cex);
      }
    }
    //MECLIPSEWTP-41 Fix the missing moduleCoreNature
    fixMissingModuleCoreNature(project, monitor);
    
    IVirtualComponent earComponent = ComponentCore.createComponent(project);
    IPath contentDirPath = new Path((contentDir.startsWith("/"))?contentDir:"/"+contentDir); //$NON-NLS-1$ //$NON-NLS-2$
    //Ensure the EarContent link has been created
    if (!WTPProjectsUtil.hasLink(project, ROOT_PATH, contentDirPath, monitor)) {
      earComponent.getRootFolder().createLink(contentDirPath, IVirtualResource.NONE, monitor);
    }
    WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(earComponent.getRootFolder(), contentDirPath, monitor);

    //MECLIPSEWTP-56 : application.xml should not be generated in the source directory
    boolean useBuildDirectory = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().getPreferences(project).isApplicationXmGeneratedInBuildDirectory();
    boolean useResourcefiltering = config.isFilteringDeploymentDescriptorsEnabled();
    
    List<IPath> sourcePaths = new ArrayList<>();
    sourcePaths.add(contentDirPath);
    
    if (!useBuildDirectory && useResourcefiltering) {
        mavenMarkerManager.addMarker(project, MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID, 
                                    Messages.markers_mavenarchiver_output_settings_ignored_warning, -1, IMarker.SEVERITY_WARNING);
    }
    if (useBuildDirectory || useResourcefiltering) {
      IPath m2eclipseWtpFolderPath = new Path("/").append(ProjectUtils.getM2eclipseWtpFolder(mavenProject, project)); //$NON-NLS-1$
      ProjectUtils.hideM2eclipseWtpFolder(mavenProject, project);
      IPath generatedResourcesPath = m2eclipseWtpFolderPath.append(Path.SEPARATOR+MavenWtpConstants.EAR_RESOURCES_FOLDER);
      sourcePaths.add(generatedResourcesPath);
      if (!WTPProjectsUtil.hasLink(project, ROOT_PATH, generatedResourcesPath, monitor)) {
        WTPProjectsUtil.insertLinkBefore(project, generatedResourcesPath, contentDirPath, ROOT_PATH, monitor);      
      }
     }

    //MECLIPSEWTP-161 remove stale source paths
    WTPProjectsUtil.deleteLinks(project, ROOT_PATH, sourcePaths, monitor);
    
    removeTestFolderLinks(project, mavenProject, monitor, "/"); //$NON-NLS-1$
    
    ProjectUtils.removeNature(project, JavaCore.NATURE_ID, monitor);

    String finalName = config.getFinalName();
    if (!finalName.endsWith(".ear")) { //$NON-NLS-1$
      finalName += ".ear"; //$NON-NLS-1$
    }
    configureDeployedName(project, finalName);
    project.refreshLocal(IResource.DEPTH_INFINITE, monitor);

    
    //MECLIPSEWTP-221 : add (in|ex)clusion patterns as .component metadata
    addComponentExclusionPatterns(earComponent, config);
    
    setModuleDependencies(project, mavenProject, monitor);
  }

  private IDataModel getEarModel(String contentDir) {
    IDataModel earModelCfg = DataModelFactory.createDataModel(new EarFacetInstallDataModelProvider());
    earModelCfg.setProperty(IEarFacetInstallDataModelProperties.CONTENT_DIR, contentDir);
    earModelCfg.setProperty(IEarFacetInstallDataModelProperties.GENERATE_DD, false);
    return earModelCfg;
  }

  @Override
public void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
      throws CoreException {
    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
    if(!facetedProject.hasProjectFacet(WTPProjectsUtil.EAR_FACET)) {
      return;
    }
    IVirtualComponent earComponent = ComponentCore.createComponent(project);
    
    Set<IVirtualReference> newRefs = new LinkedHashSet<>();
    
    EarPluginConfiguration config = new EarPluginConfiguration(mavenProject);
    // Retrieving all ear module configuration from maven-ear-plugin : User defined modules + artifacts dependencies.
    
    Set<EarModule> earModules = config.getEarModules();

    String libBundleDir = config.getDefaultBundleDirectory();

    updateLibDir(project, libBundleDir, monitor);
    
    IPackagingConfiguration packagingConfig = new PackagingConfiguration(config.getPackagingIncludes(), config.getPackagingExcludes());
    
    for(EarModule earModule : earModules) {

      Artifact artifact = earModule.getArtifact();
      IVirtualComponent depComponent = null;
      IMavenProjectFacade workspaceDependency = projectManager.getMavenProject(artifact.getGroupId(), artifact
          .getArtifactId(), artifact.getVersion());

      if(workspaceDependency != null && !workspaceDependency.getProject().equals(project)
          && workspaceDependency.getFullPath(artifact.getFile()) != null) {
        //artifact dependency is a workspace project
        IProject depProject = preConfigureDependencyProject(workspaceDependency, monitor);
        if (ModuleCoreNature.isFlexibleProject(depProject)) {
          depComponent = createDependencyComponent(earComponent, depProject);
        }
      } else {
        //artifact dependency should be added as a JEE module, referenced with M2_REPO variable 
        depComponent = createDependencyComponent(earComponent, earModule.getArtifact());
      }
      
      if (depComponent != null && packagingConfig.isPackaged(earModule.getUri())) {
        IVirtualReference depRef = ComponentCore.createReference(earComponent, depComponent);
        String bundleDir = (StringUtils.isBlank(earModule.getBundleDir()))?"/":earModule.getBundleDir(); //$NON-NLS-1$
        depRef.setRuntimePath(new Path(bundleDir));
        depRef.setArchiveName(earModule.getBundleFileName());
        newRefs.add(depRef);
      }
    }
    
    IVirtualReference[] newRefsArray = new IVirtualReference[newRefs.size()];
    newRefs.toArray(newRefsArray);
    
    //Only change the project references if they've changed
    if (hasChanged(earComponent.getReferences(), newRefsArray)) {
      earComponent.setReferences(newRefsArray);
    }

    boolean useBuildDirectory = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().getPreferences(project).isApplicationXmGeneratedInBuildDirectory();
    DeploymentDescriptorManagement.INSTANCE.updateConfiguration(project, mavenProject, config, useBuildDirectory, monitor);
  }



  private void updateLibDir(IProject project, String newLibDir, IProgressMonitor monitor) {
    //Update lib dir only applies to Java EE 5 ear projects
    if(!J2EEProjectUtilities.isJEEProject(project)){ 
      return;
    }
    
    //if the ear project Java EE level was < 5.0, the following would throw a ClassCastException  
    final IEARModelProvider earModel = (IEARModelProvider)ModelProviderManager.getModelProvider(project);
    if (earModel == null) {
      return;
    }
    final Application app = (Application)earModel.getModelObject();
    if (app != null) {
      if (newLibDir == null || "/".equals(newLibDir)) { //$NON-NLS-1$
        newLibDir = "lib"; //$NON-NLS-1$
      } 
      //MECLIPSEWTP-167 : lib directory mustn't start with a slash
      else if (newLibDir.startsWith("/")) { //$NON-NLS-1$
        newLibDir = newLibDir.substring(1);
      }
      String oldLibDir = app.getLibraryDirectory();
      if (newLibDir.equals(oldLibDir)) return;
      final String libDir = newLibDir;
      earModel.modify(new Runnable() {
        @Override
		public void run() {     
        app.setLibraryDirectory(libDir);
      }}, null);
    }
  }


  private IVirtualComponent createDependencyComponent(IVirtualComponent earComponent, IProject project) {
    IVirtualComponent depComponent = ComponentCore.createComponent(project);
    return depComponent;
  }

  private IVirtualComponent createDependencyComponent(IVirtualComponent earComponent, Artifact artifact) {
      //Create dependency component, referenced from the local Repo.
      String artifactPath = ArtifactHelper.getM2REPOVarPath(artifact);
      IVirtualComponent depComponent = ComponentCore.createArchiveComponent(earComponent.getProject(), artifactPath);
      return depComponent;
  }
}
