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

package org.eclipse.m2e.wtp;

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

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
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.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.IClasspathAttribute;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.facet.IJ2EEModuleFacetInstallDataModelProperties;
import org.eclipse.jst.j2ee.web.project.facet.IWebFacetInstallDataModelProperties;
import org.eclipse.jst.j2ee.web.project.facet.WebFacetInstallDataModelProvider;
import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.embedder.ArtifactKey;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.jdt.IClasspathDescriptor;
import org.eclipse.m2e.jdt.IClasspathEntryDescriptor;
import org.eclipse.m2e.wtp.internal.ExtensionReader;
import org.eclipse.m2e.wtp.internal.Messages;
import org.eclipse.m2e.wtp.internal.filtering.WebResourceFilteringConfiguration;
import org.eclipse.m2e.wtp.namemapping.FileNameMapping;
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.IVirtualFolder;
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;



/**
 * Configures web projects based on their maven-war-plugin configuration.
 * 
 * @author Igor Fedorenko
 * @author Fred Bricon
 */
@SuppressWarnings("restriction")
class WebProjectConfiguratorDelegate extends AbstractProjectConfiguratorDelegate {

  //private static final Logger LOG = LoggerFactory.getLogger(WebProjectConfiguratorDelegate.class);
  /**
   * See http://wiki.eclipse.org/ClasspathEntriesPublishExportSupport
   */
  static final IClasspathAttribute DEPENDENCY_ATTRIBUTE = JavaCore.newClasspathAttribute(
      IClasspathDependencyConstants.CLASSPATH_COMPONENT_DEPENDENCY, "/WEB-INF/lib"); //$NON-NLS-1$

  /**
  * Name of maven property that overrides WTP context root.
  */
  private static final String M2ECLIPSE_WTP_CONTEXT_ROOT = "m2eclipse.wtp.contextRoot"; //$NON-NLS-1$
  
  @Override
protected void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
      throws CoreException {
    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
    IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().create(project.getFile(IMavenConstants.POM_FILE_NAME), true, monitor);

    // make sure to update the main deployment folder
    WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project);
    String warSourceDirectory = config.getWarSourceDirectory();
    
    IFolder contentFolder = project.getFolder(warSourceDirectory);

    Set<Action> actions = new LinkedHashSet<>();

    installJavaFacet(actions, project, facetedProject);
    
    IVirtualComponent component = ComponentCore.createComponent(project, true);
    
    //MNGECLIPSE-2279 get the context root from the final name of the project, or artifactId by default.
    String contextRoot = getContextRoot(mavenProject, config.getWarName());
    
    IProjectFacetVersion webFv = config.getWebFacetVersion(project);
    IDataModel webModelCfg = getWebModelConfig(warSourceDirectory, contextRoot);
    if(!facetedProject.hasProjectFacet(WebFacetUtils.WEB_FACET)) {
      removeConflictingFacets(facetedProject, webFv, actions);
      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, webFv, webModelCfg));
    } else {
      IProjectFacetVersion projectFacetVersion = facetedProject.getProjectFacetVersion(WebFacetUtils.WEB_FACET);     
      if(webFv.getVersionString() != null && !webFv.getVersionString().equals(projectFacetVersion.getVersionString())){
          actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, webFv, webModelCfg));
      }
    }

    String customWebXml = config.getCustomWebXml(project);
    
    if(!actions.isEmpty()) {
      ResourceCleaner fileCleaner = new ResourceCleaner(project, contentFolder);
      try {
        addFoldersToClean(fileCleaner, facade);
        fileCleaner.addFiles(contentFolder.getFile("META-INF/MANIFEST.MF").getProjectRelativePath()); //$NON-NLS-1$
        fileCleaner.addFolder(contentFolder.getFolder("WEB-INF/lib")); //$NON-NLS-1$
        if (customWebXml != null) {
          fileCleaner.addFiles(contentFolder.getFile("WEB-INF/web.xml").getProjectRelativePath()); //$NON-NLS-1$
        }
        
        facetedProject.modify(actions, monitor);
      } finally {
        //Remove any unwanted MANIFEST.MF the Facet installation has created
        fileCleaner.cleanUp();
      }
    }
    
    //MECLIPSEWTP-41 Fix the missing moduleCoreNature
    fixMissingModuleCoreNature(project, monitor);
    
    // MNGECLIPSE-632 remove test sources/resources from WEB-INF/classes
    removeTestFolderLinks(project, mavenProject, monitor, "/WEB-INF/classes"); //$NON-NLS-1$

    addContainerAttribute(project, DEPENDENCY_ATTRIBUTE, monitor);

    //MNGECLIPSE-2279 change the context root if needed
    if (!contextRoot.equals(J2EEProjectUtilities.getServerContextRoot(project))) {
      J2EEProjectUtilities.setServerContextRoot(project, contextRoot);
    }
    
    if (customWebXml != null) {
      linkFileFirst(project, customWebXml, "/WEB-INF/web.xml", monitor); //$NON-NLS-1$
    }

    
    component = ComponentCore.createComponent(project, true);
    if(component != null) {      
      IVirtualFolder rootFolder = component.getRootFolder();
      IPath warPath = new Path("/").append(contentFolder.getProjectRelativePath()); //$NON-NLS-1$
      boolean warPathExists = WTPProjectsUtil.hasLink(project, ROOT_PATH, warPath, monitor);
      if (!warPathExists) {
        component.getRootFolder().createLink(warPath, IVirtualResource.NONE, monitor); 
      }
      IPath currentDefaultLocation = J2EEModuleVirtualComponent.getDefaultDeploymentDescriptorFolder(rootFolder);
      if (currentDefaultLocation == null) {
    	  WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(rootFolder , warPath, monitor);
      }
      //MECLIPSEWTP-22 support web filtered resources. Filtered resources directory must be declared BEFORE
      //the regular web source directory. First resources discovered take precedence on deployment
      IPath filteredFolder = new Path("/").append(WebResourceFilteringConfiguration.getTargetFolder(mavenProject, project)); //$NON-NLS-1$
      
      boolean useBuildDir = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().getPreferences(project).isWebMavenArchiverUsesBuildDirectory();
      boolean useWebresourcefiltering = config.getWebResources() != null 
                                        && config.getWebResources().length > 0 
                                        || config.isFilteringDeploymentDescriptorsEnabled();

      if (useBuildDir || useWebresourcefiltering) {
        
        if (!useBuildDir && useWebresourcefiltering) {
          mavenMarkerManager.addMarker(project, MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID, 
                                      Messages.markers_mavenarchiver_output_settings_ignored_warning, -1, IMarker.SEVERITY_WARNING);
        }
        if (!WTPProjectsUtil.hasLink(project, ROOT_PATH, filteredFolder, monitor)) {
        	WTPProjectsUtil.insertLinkBefore(project, filteredFolder, warPath, ROOT_PATH, monitor);
        }
      } else {
        component.getRootFolder().removeLink(filteredFolder,IVirtualResource.NONE, monitor);
      }

      addComponentExclusionPatterns(component, config);
    }
    WTPProjectsUtil.removeWTPClasspathContainer(project);
    
    setModuleDependencies(project, mavenProject, monitor);
  }

  private IDataModel getWebModelConfig(String warSourceDirectory, String contextRoot) {
    IDataModel webModelCfg = DataModelFactory.createDataModel(new WebFacetInstallDataModelProvider());
    webModelCfg.setProperty(IJ2EEModuleFacetInstallDataModelProperties.CONFIG_FOLDER, warSourceDirectory);
    webModelCfg.setProperty(IWebFacetInstallDataModelProperties.CONTEXT_ROOT, contextRoot);
    webModelCfg.setProperty(IJ2EEModuleFacetInstallDataModelProperties.GENERATE_DD, false);
    webModelCfg.setBooleanProperty(IWebFacetInstallDataModelProperties.ADD_TO_EAR, false);
    return webModelCfg;
  }

  @Override
  public void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
      throws CoreException {
    if (!ModuleCoreNature.isFlexibleProject(project)) {
      return;
    }
    
    IVirtualComponent component = ComponentCore.createComponent(project,true);
    //if the attempt to create dependencies happens before the project is actually created, abort. 
    //this will be created again when the project exists.
    if(component == null){
      return;
    }
    //MECLIPSEWTP-41 Fix the missing moduleCoreNature
    fixMissingModuleCoreNature(project, monitor);
    
    WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project);
   
    Map<Artifact, String> deployedArtifacts = getDeployedArtifacts(mavenProject.getArtifacts(), config);
    
    List<AbstractDependencyConfigurator> depConfigurators = ExtensionReader.readDependencyConfiguratorExtensions(projectManager, 
        MavenPlugin.getMavenRuntimeManager(), mavenMarkerManager);
    
    Set<IVirtualReference> references = new LinkedHashSet<>();

    List<IMavenProjectFacade> exportedDependencies = getWorkspaceDependencies(project, mavenProject);
    
    for(IMavenProjectFacade dependency : exportedDependencies) {
      String depPackaging = dependency.getPackaging();
      if ("pom".equals(depPackaging) //MNGECLIPSE-744 pom dependencies shouldn't be deployed //$NON-NLS-1$
          || "war".equals(depPackaging) //Overlays are dealt with the overlay configurator //$NON-NLS-1$
          || "zip".equals(depPackaging)) { //$NON-NLS-1$
        continue;
      }
      
      preConfigureDependencyProject(dependency, monitor);
      
      if (!ModuleCoreNature.isFlexibleProject(dependency.getProject())) {
        //Projects unsupported by WTP (ex. adobe flex projects) should not be added as references
        continue;
      }
      MavenProject depMavenProject =  dependency.getMavenProject(monitor);

      IVirtualComponent depComponent = ComponentCore.createComponent(dependency.getProject());
		      
      ArtifactKey artifactKey = ArtifactHelper.toArtifactKey(depMavenProject.getArtifact());
      //Get artifact using the proper classifier
      Artifact artifact = ArtifactHelper.getArtifact(mavenProject.getArtifacts(), artifactKey);
      if (artifact == null) {
        //could not map key to artifact
        artifact = depMavenProject.getArtifact();
      }
      String deployedName = deployedArtifacts.get(artifact);
      
  		//an artifact in mavenProject.getArtifacts() doesn't have the "optional" value as depMavenProject.getArtifact();  
  		if (deployedName != null) {
  		  IVirtualReference reference = ComponentCore.createReference(component, depComponent);
  		  IPath path = new Path("/WEB-INF/lib"); //$NON-NLS-1$
  		  reference.setArchiveName(deployedName);
  		  reference.setRuntimePath(path);
  		  references.add(reference);
  		}
    }

    IVirtualReference[] oldRefs = WTPProjectsUtil.extractHardReferences(component, false);
    
    IVirtualReference[] newRefs = references.toArray(new IVirtualReference[references.size()]);
    
    if (WTPProjectsUtil.hasChanged(oldRefs, newRefs)){
      //Only write in the .component file if necessary 
      IVirtualReference[] overlayRefs = WTPProjectsUtil.extractHardReferences(component, true);
      IVirtualReference[] allRefs = new IVirtualReference[overlayRefs.length + newRefs.length];
      System.arraycopy(newRefs, 0, allRefs, 0, newRefs.length);
      System.arraycopy(overlayRefs, 0, allRefs, newRefs.length, overlayRefs.length);
      component.setReferences(allRefs);
    }
    
    //TODO why a 2nd loop???
    for(IMavenProjectFacade dependency : exportedDependencies) {
      MavenProject depMavenProject =  dependency.getMavenProject(monitor);
      Iterator<AbstractDependencyConfigurator> configurators = depConfigurators.iterator();
      while (configurators.hasNext()) {
        try {
          configurators.next().configureDependency(mavenProject, project, depMavenProject, dependency.getProject(), monitor);
        } catch(MarkedException ex) {
          //XXX handle this
        }
      }
    }
  }
  
  /**
   * Get the context root from a maven web project
   * @param mavenProject
   * @param warName 
   * @return the final name of the project if it exists, or the project's artifactId.
   */
  protected String getContextRoot(MavenProject mavenProject, String warName) {
    String contextRoot;
	//MECLIPSEWTP-43 : Override with maven property
   String property = mavenProject.getProperties().getProperty(M2ECLIPSE_WTP_CONTEXT_ROOT);
   if (StringUtils.isBlank(property)) {
  		String finalName = warName;
  		if (StringUtils.isBlank(finalName) 
  		   || finalName.equals(mavenProject.getArtifactId() + "-" + mavenProject.getVersion())) { //$NON-NLS-1$
  		  contextRoot = mavenProject.getArtifactId();
  		}  else {
  		  contextRoot = finalName;
  		}
  	} else {
  		contextRoot = property;
  	}

    return contextRoot.trim().replace(" ", "_"); //$NON-NLS-1$ //$NON-NLS-2$
  }

  @Override
  public void configureClasspath(IProject project, MavenProject mavenProject, IClasspathDescriptor classpath,
      IProgressMonitor monitor) throws CoreException {
    
    WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project);
    Set<Artifact> artifacts = mavenProject.getArtifacts();
    Map<Artifact, String> deployedArtifacts = getDeployedArtifacts(artifacts, config);
    
    Iterator<IClasspathEntryDescriptor> iter = classpath.getEntryDescriptors().iterator();
    while (iter.hasNext()) {
      IClasspathEntryDescriptor descriptor = iter.next();
      Artifact artifact = ArtifactHelper.getArtifact(artifacts, descriptor.getArtifactKey());
      if (artifact == null) {
        return;
      }
      
      String deployedName = deployedArtifacts.get(artifact);
    
      if(deployedName == null || isWorkspaceProject(artifact)) {
        descriptor.setClasspathAttribute(NONDEPENDENCY_ATTRIBUTE.getName(), NONDEPENDENCY_ATTRIBUTE.getValue());
        continue;
      }
      descriptor.getClasspathAttributes().put(IClasspathDependencyConstants.CLASSPATH_ARCHIVENAME_ATTRIBUTE, deployedName);
    }
  }

  private boolean isWorkspaceProject(Artifact artifact) {
	  IMavenProjectFacade facade = projectManager.getMavenProject(artifact.getGroupId(), 
																	artifact.getArtifactId(),
																	artifact.getVersion());
		      
	  return facade != null && facade.getFullPath(artifact.getFile()) != null;
  }
 
  private Map<Artifact, String> getDeployedArtifacts(Collection<Artifact> artifacts, WarPluginConfiguration config ) {
    if (artifacts == null || artifacts.isEmpty()) {
      return Collections.emptyMap();
    }
    int size = artifacts.size();
    Map<Artifact, String> artifactsMap = new LinkedHashMap<>(size);
    
    IPackagingConfiguration opts = new PackagingConfiguration(config.getPackagingIncludes(), config.getPackagingExcludes());
    FileNameMapping fileNameMapping = config.getFileNameMapping();
    
    Set<String> names = new HashSet<>(size);

    Set<String> duplicates = new HashSet<>(size);
    
    for (Artifact artifact : artifacts) {
      ArtifactHelper.fixArtifactHandler(artifact.getArtifactHandler());
      String deployedName = fileNameMapping.mapFileName(artifact);
      String scope = artifact.getScope();
    	boolean isDeployed =  (Artifact.SCOPE_COMPILE.equals(scope) || Artifact.SCOPE_RUNTIME.equals(scope)) 
    	                      && !artifact.isOptional()
    	                      && opts.isPackaged("WEB-INF/lib/"+deployedName); //$NON-NLS-1$
    	if (isDeployed) {
    	  if (!names.add(deployedName)) {
    		  duplicates.add(deployedName);
     	  }
    	  artifactsMap.put(artifact, deployedName);
    	}
	  }
    
    //disambiguate duplicates
    for (String name : duplicates) {
    	for (Map.Entry<Artifact, String> entry : artifactsMap.entrySet()) {
    		if (name.equals(entry.getValue())) {
    		    String newDeployedName = entry.getKey().getGroupId() + "-" + name; //$NON-NLS-1$
    			entry.setValue(newDeployedName);
    		}
    	}
    }
    
    return artifactsMap;
  }
  
}
