/*******************************************************************************
 * 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.internal.StringUtils.joinAsString;

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

import org.apache.maven.artifact.Artifact;
import org.apache.maven.project.MavenProject;
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.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.internal.MavenPluginActivator;
import org.eclipse.m2e.core.internal.markers.IMavenMarkerManager;
import org.eclipse.m2e.core.internal.markers.SourceLocation;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.IMavenProjectRegistry;
import org.eclipse.m2e.core.project.MavenProjectUtils;
import org.eclipse.m2e.jdt.IClasspathDescriptor;
import org.eclipse.m2e.wtp.internal.Messages;
import org.eclipse.m2e.wtp.internal.utilities.DebugUtilities;
import org.eclipse.m2e.wtp.internal.webfragment.WebFragmentUtil;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
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.ProjectFacetsManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Base class to configure JavaEE projects
 * 
 * @author Igor Fedorenko
 * @author Fred Bricon
 * 
 * @provisional This class has been added as part of a work in progress. 
 * It is not guaranteed to work or remain the same in future releases. 
 * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
 * 
 */
abstract class AbstractProjectConfiguratorDelegate implements IProjectConfiguratorDelegate {

  private static final Logger LOG = LoggerFactory.getLogger(AbstractProjectConfiguratorDelegate.class); 
  
  static final IClasspathAttribute NONDEPENDENCY_ATTRIBUTE = JavaCore.newClasspathAttribute(
      IClasspathDependencyConstants.CLASSPATH_COMPONENT_NON_DEPENDENCY, ""); //$NON-NLS-1$

  protected static final IPath ROOT_PATH = new Path("/");  //$NON-NLS-1$

  protected final IMavenProjectRegistry projectManager;

  protected final IMavenMarkerManager mavenMarkerManager;

  AbstractProjectConfiguratorDelegate() {
    this.projectManager = MavenPlugin.getMavenProjectRegistry();
    this.mavenMarkerManager = MavenPluginActivator.getDefault().getMavenMarkerManager();
  }
  
  @Override
public void configureProject(IProject project, MavenProject mavenProject, IProgressMonitor monitor) throws MarkedException {
    try {
      mavenMarkerManager.deleteMarkers(project,MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID);
      configure(project, mavenProject, monitor);
    } catch (CoreException cex) {
      //TODO Filter out constraint violations
      mavenMarkerManager.addErrorMarkers(project, MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID, cex);
      throw new MarkedException(NLS.bind(Messages.AbstractProjectConfiguratorDelegate_Unable_To_Configure_Project,project.getName()), cex);
    }
  }
 
  protected abstract void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor) throws CoreException;

  protected List<IMavenProjectFacade> getWorkspaceDependencies(IProject project, MavenProject mavenProject) {
    Set<IProject> projects = new HashSet<IProject>();
    List<IMavenProjectFacade> dependencies = new ArrayList<IMavenProjectFacade>();
    Set<Artifact> artifacts = mavenProject.getArtifacts();
    for(Artifact artifact : artifacts) {
      IMavenProjectFacade dependency = projectManager.getMavenProject(artifact.getGroupId(), artifact.getArtifactId(),
          artifact.getVersion());
      
      if((Artifact.SCOPE_COMPILE.equals(artifact.getScope()) 
          || Artifact.SCOPE_RUNTIME.equals(artifact.getScope())) //MNGECLIPSE-1578 Runtime dependencies should be deployed 
          && dependency != null && !dependency.getProject().equals(project) && dependency.getFullPath(artifact.getFile()) != null
          && projects.add(dependency.getProject())) {
        dependencies.add(dependency);
      }
    }
    return dependencies;
  }

  protected void configureWtpUtil(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
    // Adding utility facet on JEE projects is not allowed
    IProject project = facade.getProject();
    MavenProject mavenProject = facade.getMavenProject();
    if(  !WTPProjectsUtil.isJavaProject(facade)
       || WTPProjectsUtil.isJavaEEProject(project) 
       || WebFragmentUtil.isQualifiedAsWebFragment(facade)) {
      return;
    }
    
    //MECLIPSEWTP-66 delete extra MANIFEST.MF
    IPath[] sourceRoots = MavenProjectUtils.getSourceLocations(project, mavenProject.getCompileSourceRoots());
    IPath[] resourceRoots = MavenProjectUtils.getResourceLocations(project, mavenProject.getResources());
    
    //MECLIPSEWTP-182 check if the Java Project configurator has been successfully run before doing anything : 
    if (!checkJavaConfiguration(project, sourceRoots, resourceRoots)) {
      LOG.warn(NLS.bind(Messages.AbstractProjectConfiguratorDelegate_Error_Inconsistent_Java_Configuration, project.getName()));
      return;
    }

    boolean isDebugEnabled = DebugUtilities.isDebugEnabled();
    if (isDebugEnabled) {
      DebugUtilities.debug(DebugUtilities.dumpProjectState("Before configuration ",project)); //$NON-NLS-1$
    }

    // 2 - check if the manifest already exists, and its parent folder
    
    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
    Set<Action> actions = new LinkedHashSet<Action>();
    installJavaFacet(actions, project, facetedProject);

    if(!facetedProject.hasProjectFacet(WTPProjectsUtil.UTILITY_FACET)) {
      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, WTPProjectsUtil.UTILITY_10, null));
    } else if(!facetedProject.hasProjectFacet(WTPProjectsUtil.UTILITY_10)) {
      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, WTPProjectsUtil.UTILITY_10,
          null));
    }
    
    if (!actions.isEmpty()) {
      ResourceCleaner fileCleaner = new ResourceCleaner(project);
      try {
        addFoldersToClean(fileCleaner, facade);
        facetedProject.modify(actions, monitor);      
      } finally {
        //Remove any unwanted MANIFEST.MF the Facet installation has created
        fileCleaner.cleanUp();
      } 
    }
    
    fixMissingModuleCoreNature(project, monitor);
    
    if (isDebugEnabled) {
      DebugUtilities.debug(DebugUtilities.dumpProjectState("after configuration ",project)); //$NON-NLS-1$
    }
    //MNGECLIPSE-904 remove tests folder links for utility jars
    removeTestFolderLinks(project, mavenProject, monitor, "/"); //$NON-NLS-1$
    
    //Remove "library unavailable at runtime" warning.
    if (isDebugEnabled) {
      DebugUtilities.debug(DebugUtilities.dumpProjectState("after removing test folders ",project)); //$NON-NLS-1$
    }

    setNonDependencyAttributeToContainer(project, monitor);
    
    WTPProjectsUtil.removeWTPClasspathContainer(project);
  }

  /**
   * Checks the maven source folders are correctly added to the project classpath
   */
  private boolean checkJavaConfiguration(IProject project, IPath[] sourceRoots, IPath[] resourceRoots) throws JavaModelException {
    IJavaProject javaProject = JavaCore.create(project);
    if (javaProject == null) {
      return false;
    }
    IClasspathEntry[] cpEntries = javaProject.getRawClasspath();
    if (cpEntries == null) {
      return false;
    }
    Set<IPath> currentPaths = new HashSet<IPath>();
    for (IClasspathEntry entry  : cpEntries) {
      if (IClasspathEntry.CPE_SOURCE == entry.getEntryKind()){
        currentPaths.add(entry.getPath().makeRelativeTo(project.getFullPath()));
      }
    }
    for(IPath mavenSource : sourceRoots) {
        if (mavenSource != null && !mavenSource.isEmpty()) {
          IFolder sourceFolder = project.getFolder(mavenSource);
          if (sourceFolder.exists() && !currentPaths.contains(mavenSource)) {
            return false;
          }
        }
    }
    for(IPath mavenSource : resourceRoots) {
      if (mavenSource != null && !mavenSource.isEmpty()) {
        IFolder resourceFolder = project.getFolder(mavenSource);
        if (resourceFolder.exists() && !currentPaths.contains(mavenSource)) {
          return false;
        }
      }
  }
    return true;
  }

  /**
   * Add the ModuleCoreNature to a project, if necessary.
   * 
   * @param project An accessible project.
   * @param monitor A progress monitor to track the time to completion
   * @throws CoreException if the ModuleCoreNature cannot be added
   */
  protected void fixMissingModuleCoreNature(IProject project, IProgressMonitor monitor) throws CoreException {
    WTPProjectsUtil.fixMissingModuleCoreNature(project, monitor);
  }

  protected void installJavaFacet(Set<Action> actions, IProject project, IFacetedProject facetedProject) {
    WTPProjectsUtil.installJavaFacet(actions, project, facetedProject);
  }

  protected void removeTestFolderLinks(IProject project, MavenProject mavenProject, IProgressMonitor monitor,
      String folder) throws CoreException {
    WTPProjectsUtil.removeTestFolderLinks(project, mavenProject, monitor, folder);
  }

  protected void addContainerAttribute(IProject project, IClasspathAttribute attribute, IProgressMonitor monitor)
      throws JavaModelException {
    updateContainerAttributes(project, attribute, null, monitor);
  }

  protected void setNonDependencyAttributeToContainer(IProject project, IProgressMonitor monitor) throws JavaModelException {
    WTPProjectsUtil.updateContainerAttributes(project, NONDEPENDENCY_ATTRIBUTE, IClasspathDependencyConstants.CLASSPATH_COMPONENT_DEPENDENCY, monitor);
  }

  protected void updateContainerAttributes(IProject project, IClasspathAttribute attributeToAdd, String attributeToDelete, IProgressMonitor monitor)
  throws JavaModelException {
    WTPProjectsUtil.updateContainerAttributes(project, attributeToAdd, attributeToDelete, monitor);
  }

  /**
   * @param dependencyMavenProjectFacade
   * @param monitor
   * @return
   * @throws CoreException
   */
  protected IProject preConfigureDependencyProject(IMavenProjectFacade dependencyMavenProjectFacade, IProgressMonitor monitor) throws CoreException {
    IProject dependency = dependencyMavenProjectFacade.getProject();
    String depPackaging = dependencyMavenProjectFacade.getPackaging();
    //jee dependency has not been configured yet - i.e. it has no JEE facet-
    if(!JEEPackaging.isJEEPackaging(depPackaging)) {
      // XXX Probably should create a UtilProjectConfiguratorDelegate
      configureWtpUtil(dependencyMavenProjectFacade, monitor);
    }
    return dependency;
  }

  @SuppressWarnings("restriction")
  protected void configureDeployedName(IProject project, String deployedFileName) {
    //We need to remove the file extension from deployedFileName 
    int extSeparatorPos  = deployedFileName.lastIndexOf('.');
    String deployedName = extSeparatorPos > -1? deployedFileName.substring(0, extSeparatorPos): deployedFileName;
    //From jerr's patch in MNGECLIPSE-965
    IVirtualComponent projectComponent = ComponentCore.createComponent(project);
    if(projectComponent != null && !deployedName.equals(projectComponent.getDeployedName())){//MNGECLIPSE-2331 : Seems projectComponent.getDeployedName() can be null 
      StructureEdit moduleCore = null;
      try {
        moduleCore = StructureEdit.getStructureEditForWrite(project);
        if (moduleCore != null){
          WorkbenchComponent component = moduleCore.getComponent();
          if (component != null) {
            component.setName(deployedName);
            moduleCore.saveIfNecessary(null);
          }
        }
      } finally {
        if (moduleCore != null) {
          moduleCore.dispose();
        }
      }
    }  
  }

  /**
   * Link a project's file to a specific deployment destination. Existing links will be deleted beforehand. 
   * @param project 
   * @param sourceFile the existing file to deploy
   * @param targetRuntimePath the target runtime/deployment location of the file
   * @param monitor
   * @throws CoreException
   */
  protected void linkFileFirst(IProject project, String sourceFile, String targetRuntimePath, IProgressMonitor monitor) throws CoreException {
      IPath runtimePath = new Path(targetRuntimePath);
      //We first delete any existing links
      WTPProjectsUtil.deleteLinks(project, runtimePath, monitor);
      if (sourceFile != null) {
        //Create the new link
        WTPProjectsUtil.insertLinkFirst(project, new Path(sourceFile), new Path(targetRuntimePath), monitor);
      }
  }

  @Deprecated
  protected boolean hasChanged(IVirtualReference[] existingRefs, IVirtualReference[] refArray) {
      return WTPProjectsUtil.hasChanged(existingRefs, refArray);
  }

  @Override
public void configureClasspath(IProject project, MavenProject mavenProject, IClasspathDescriptor classpath,
      IProgressMonitor monitor) throws CoreException {
    // do nothing
  }

  @Override
public void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
      throws CoreException {
    // do nothing
  }
  
  protected void addFoldersToClean(ResourceCleaner fileCleaner, IMavenProjectFacade facade) {
    for (IPath p : facade.getCompileSourceLocations()) {
      if (p != null) {
        fileCleaner.addFiles(p.append("META-INF/MANIFEST.MF")); //$NON-NLS-1$
        fileCleaner.addFolder(p);
      }
    }
    for (IPath p : facade.getResourceLocations()) {
      if (p != null) {
        fileCleaner.addFiles(p.append("META-INF/MANIFEST.MF")); //$NON-NLS-1$
        fileCleaner.addFolder(p);
      }
    }
    // add default resource folder
    IPath defaultResource = new Path("src/main/resources"); //$NON-NLS-1$
    fileCleaner.addFiles(defaultResource.append("META-INF/MANIFEST.MF")); //$NON-NLS-1$
    fileCleaner.addFolder(defaultResource);
    
    for (IPath p : facade.getTestCompileSourceLocations()) {
      if (p != null) fileCleaner.addFolder(p);
    }
    for (IPath p : facade.getTestResourceLocations()) {
      if (p != null) fileCleaner.addFolder(p);
    }
  }
  
  /**
   * Add inclusion/exclusion patterns to .component metadata. WTP server adapters can use that information to 
   * include/exclude resources from deployment accordingly. This is currently implemented in the JBoss AS server adapter.
   * @throws CoreException 
   */
  protected void addComponentExclusionPatterns(IVirtualComponent component, IMavenPackageFilter filter)  {
    String[] warSourceIncludes = filter.getSourceIncludes();
    String[] packagingIncludes = filter.getPackagingIncludes();
    String[] warSourceExcludes = filter.getSourceExcludes();
    String[] packagingExcludes = filter.getPackagingExcludes();
    
    if (warSourceIncludes.length > 0 && packagingIncludes.length >0) {
      IResource pomFile = component.getProject().getFile(IMavenConstants.POM_FILE_NAME);
      // We might get bad pattern overlapping (**/* + **/*.html would return everything, 
      // when maven would only package html files) . 
      // So we arbitrary (kinda) keep the packaging patterns only. But this can lead to other funny discrepancies 
      // things like **/pages/** + **/*.html should return only html files from the pages directory, but here, will return
      // every html files.
      SourceLocation sourceLocation = filter.getSourceLocation();
      if (sourceLocation != null) {
        mavenMarkerManager.addMarker(pomFile, 
                                   MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID,
                                   NLS.bind(Messages.markers_inclusion_patterns_problem, filter.getSourceIncludeParameterName()), 
                                   sourceLocation.getLineNumber(), 
                                   IMarker.SEVERITY_WARNING);
      }
      warSourceIncludes = null;
    }
    String componentInclusions = joinAsString(warSourceIncludes, packagingIncludes);
    String componentExclusions = joinAsString(warSourceExcludes, packagingExcludes);
    Properties props = component.getMetaProperties();
    if (!componentInclusions.equals(props.getProperty(MavenWtpConstants.COMPONENT_INCLUSION_PATTERNS, ""))) { //$NON-NLS-1$
      component.setMetaProperty(MavenWtpConstants.COMPONENT_INCLUSION_PATTERNS, componentInclusions);
    }
    if (!componentExclusions.equals(props.getProperty(MavenWtpConstants.COMPONENT_EXCLUSION_PATTERNS, ""))) { //$NON-NLS-1$
      component.setMetaProperty(MavenWtpConstants.COMPONENT_EXCLUSION_PATTERNS, componentExclusions);
    }
  }
  
}
