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


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

import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.MavenExecutionPlan;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomUtils;
import org.eclipse.core.resources.IContainer;
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.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.embedder.IMaven;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.internal.MavenPluginActivator;
import org.eclipse.m2e.core.internal.builder.plexusbuildapi.AbstractEclipseBuildContext;
import org.eclipse.m2e.core.internal.builder.plexusbuildapi.AbstractEclipseBuildContext.Message;
import org.eclipse.m2e.core.internal.builder.plexusbuildapi.EclipseBuildContext;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.IMavenProjectRegistry;
import org.eclipse.m2e.core.project.ResolverConfiguration;
import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
import org.eclipse.m2e.wtp.DomUtils;
import org.eclipse.m2e.wtp.MavenWtpConstants;
import org.eclipse.m2e.wtp.WTPProjectsUtil;
import org.eclipse.m2e.wtp.internal.Messages;
import org.eclipse.osgi.util.NLS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonatype.plexus.build.incremental.BuildContext;
import org.sonatype.plexus.build.incremental.ThreadBuildContext;

/**
 * ResourceFilteringBuildParticipant
 *
 * @author Fred Bricon
 */
@SuppressWarnings("restriction")
public class ResourceFilteringBuildParticipant extends AbstractBuildParticipant {
  
  private static final Logger LOG = LoggerFactory.getLogger(ResourceFilteringBuildParticipant.class );

  //Need to duplicate org.eclipse.m2e.core.internal.builder.MavenBuilder.BUILD_CONTEXT_KEY since it's not accessible 
  private static final QualifiedName BUILD_CONTEXT_KEY = new QualifiedName(IMavenConstants.PLUGIN_ID, "BuildContext"); //$NON-NLS-1$
  
  private EclipseBuildContext forceCopyBuildContext; 
  
  @Override
  public Set<IProject> build(int kind, IProgressMonitor monitor) throws Exception {
    IMavenProjectFacade facade = getMavenProjectFacade();
    ResourceFilteringConfiguration configuration = ResourceFilteringConfigurationFactory.getConfiguration(facade);
    List<Xpp3Dom> resources = null;
    if (configuration == null || (resources = configuration.getResources()) == null) {
      //Nothing to filter
      return null;
    }

    IProject project = facade.getProject();
    //FIXME assuming path relative to current project
    IPath targetFolder = configuration.getTargetFolder();
    IResourceDelta delta = getDelta(project);

    BuildContext oldBuildContext = ThreadBuildContext.getContext();
    
    try {
      forceCopyBuildContext = null;
      List<String> filters = configuration.getFilters();
      if (changeRequiresForcedCopy(facade, filters, delta)) {
        LOG.info(NLS.bind(Messages.ResourceFilteringBuildParticipant_Changed_Resources_Require_Clean_Build,project.getName()));
        Map<String, Object> contextState = new HashMap<String, Object>();
        project.setSessionProperty(BUILD_CONTEXT_KEY, contextState);
        //String id = "" + "-" + getClass().getName();
        forceCopyBuildContext = new EclipseBuildContext(project, contextState);
        forceCopyBuildContext.setCurrentBuildParticipantId(getBuildParticipantId());
        ThreadBuildContext.setThreadBuildContext(forceCopyBuildContext);
      }
      if (forceCopyBuildContext != null || hasResourcesChanged(facade, delta, resources)) {
        LOG.info(NLS.bind(Messages.ResourceFilteringBuildParticipant_Executing_Resource_Filtering,project.getName()));
        executeCopyResources(facade, configuration, targetFolder, resources, monitor);
        //FIXME deal with absolute paths
        IFolder destFolder = project.getFolder(targetFolder);
        if (destFolder.exists()){
          destFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
        }
      }
    } finally {
      ThreadBuildContext.setThreadBuildContext(oldBuildContext);
    }

    return null;
  }

  /**
   * Workaround to retrieve the buildParticipantId that is not exposed by AbstractEclipseBuildContext
   */
  private String getBuildParticipantId() {
    BuildContext originalContext = super.getBuildContext();
    String id = "org.apache.maven.plugins:maven-resources:copy-resources:::-"+getClass().getName();  //$NON-NLS-1$
    if (originalContext != null && (originalContext instanceof AbstractEclipseBuildContext)) {
      //That allows us to avoid doing some introspection
      AbstractEclipseBuildContext eclipseContext = ((AbstractEclipseBuildContext)originalContext); 
      Map<String, List<Message>> map = eclipseContext.getMessages();
      if (map == null || map.isEmpty()) {
        eclipseContext.addMessage(null, 0, 0, "dummy", 0, null); //$NON-NLS-1$
        //adding a message initializes the map 
        map = eclipseContext.getMessages();
        id = map.keySet().iterator().next();
        map.clear();
      } else {
        id = map.keySet().iterator().next();
      }
    }
    return id;
  }

  @Override
protected BuildContext getBuildContext() {
     return (forceCopyBuildContext == null)?super.getBuildContext() : forceCopyBuildContext;
  }

   /**
  * If the pom.xml or any of the project's filters were changed, a forced copy is required
  * @param facade
  * @param delta
  * @return
  */
   private boolean changeRequiresForcedCopy(IMavenProjectFacade facade, List<String> filters, IResourceDelta delta) {
     if (delta == null) {
       return false;
     }
  
     if (delta.findMember(facade.getPom().getProjectRelativePath()) != null ) {
       return true;
     }
     
     for (String filter : filters) {       
       IPath filterPath = facade.getProjectRelativePath(filter);
       if (filterPath == null) {
         filterPath =Path.fromOSString(filter);
       }
       if (delta.findMember(filterPath) != null){
         return true;
       }
     }
     return false;
     
   }
 
  @Override
public void clean(IProgressMonitor monitor) throws CoreException {
    IMavenProjectFacade facade = getMavenProjectFacade();
    ResourceFilteringConfiguration configuration = ResourceFilteringConfigurationFactory.getConfiguration(facade);
    if (configuration == null) {
      //Nothing to do
      return;
    }

    IProject project = facade.getProject();
    IPath targetFolderPath = configuration.getTargetFolder();
    deleteFilteredResources(project, targetFolderPath);
    super.clean(monitor);
  }
  
  private void deleteFilteredResources(IProject project, IPath targetFolderPath) throws CoreException {
    IFolder targetFolder = project.getFolder(targetFolderPath);
    if (targetFolder.exists()) {
      IContainer parent = targetFolder.getParent(); 
      LOG.info(NLS.bind(Messages.ResourceFilteringBuildParticipant_Cleaning_Filtered_Folder,project.getName()));
      IProgressMonitor monitor =new NullProgressMonitor();
      targetFolder.delete(true, monitor);
      if (parent != null) {
        parent.refreshLocal(IResource.DEPTH_INFINITE, monitor ); 
      }
    }    
  }

  
  /**
   * @param mavenProject
   * @param iResourceDelta 
   * @param resources
   * @return
   */
  private boolean hasResourcesChanged(IMavenProjectFacade facade, IResourceDelta delta, List<Xpp3Dom> resources) {
    if (resources == null || resources.isEmpty()){
      return false;
    }
      
    Set<IPath> resourcePaths = getResourcePaths(facade, resources);
  
    if(delta == null) {
      return !resourcePaths.isEmpty();
    }
  
    for(IPath resourcePath : resourcePaths) {
      IResourceDelta member = delta.findMember(resourcePath);
      //XXX deal with member kind/flags
      if(member != null) {
          return true; 
          //we need to deal with superceded resources on the maven level
      }
    }
  
    return false;
  }

  
  private Set<IPath> getResourcePaths(IMavenProjectFacade facade, List<Xpp3Dom> resources) {
    Set<IPath> resourcePaths = new LinkedHashSet<IPath>();
    for(Xpp3Dom resource : resources) {
      IPath folder= null;
      Xpp3Dom xpp3Directory = resource.getChild("directory"); //$NON-NLS-1$
      if (xpp3Directory != null)
      {
        String dir = xpp3Directory.getValue();
        if (StringUtils.isNotEmpty(dir)){
          folder = WTPProjectsUtil.tryProjectRelativePath(facade.getProject(), dir);          
        }
      }
      if(folder != null && !folder.isEmpty()) {
        resourcePaths.add(folder);
      }
    }

    return resourcePaths;
  }
  

  private void executeCopyResources(IMavenProjectFacade facade,  ResourceFilteringConfiguration filteringConfiguration, IPath targetFolder, List<Xpp3Dom> resources, IProgressMonitor monitor) throws CoreException {

    //Create a maven request + session
    ResolverConfiguration resolverConfig = facade.getResolverConfiguration();
    
    List<String> filters = filteringConfiguration.getFilters();
    IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry();
    MavenExecutionRequest request = projectManager.createExecutionRequest(facade.getPom(), resolverConfig, monitor);
    request.setRecursive(false);
    request.setOffline(true);

    IMaven maven = MavenPlugin.getMaven();
    MavenProject mavenProject = facade.getMavenProject();
    
    MavenSession session = maven.createSession(request, mavenProject);
    MavenExecutionPlan executionPlan = maven.calculateExecutionPlan(session, mavenProject, Collections.singletonList("resources:copy-resources"), true, monitor); //$NON-NLS-1$
    
    MojoExecution copyFilteredResourcesMojo = getExecution(executionPlan, "maven-resources-plugin"); //$NON-NLS-1$

    if (copyFilteredResourcesMojo == null) return;

    Xpp3Dom originalConfig = copyFilteredResourcesMojo.getConfiguration();
    Xpp3Dom  configuration = Xpp3DomUtils.mergeXpp3Dom(new Xpp3Dom("configuration"), originalConfig); //$NON-NLS-1$
    boolean parentHierarchyLoaded = false;
    try {
      parentHierarchyLoaded = loadParentHierarchy(facade, monitor);
      
      //Set resource directories to read
      setupResources(configuration, resources);
      
      //Force overwrite
      setValue(configuration, "overwrite", Boolean.TRUE); //$NON-NLS-1$
      
      //Limit placeholder delimiters, otherwise, pages containing @ wouldn't be filtered correctly
      setupDelimiters(configuration);
      
      //Set output directory to the m2eclipse-wtp webresources directory
      setValue(configuration, "outputDirectory", targetFolder.toPortableString()); //$NON-NLS-1$
      
      setValue(configuration, "escapeString", filteringConfiguration.getEscapeString()); //$NON-NLS-1$

      setNonfilteredExtensions(configuration, filteringConfiguration.getNonfilteredExtensions());

      //Setup filters
      setupFilters(configuration, filters);

      //Create a maven request + session
      request.setRecursive(false);
      request.setOffline(true);

      //Execute our modified mojo 
      copyFilteredResourcesMojo.setConfiguration(configuration);
      copyFilteredResourcesMojo.getMojoDescriptor().setGoal("copy-resources"); //$NON-NLS-1$

      maven.execute(session, copyFilteredResourcesMojo, monitor);
      
      if (session.getResult().hasExceptions()){
        
          MavenPluginActivator.getDefault().getMavenMarkerManager().addMarker(facade.getProject(), MavenWtpConstants.WTP_MARKER_FILTERING_ERROR,Messages.ResourceFilteringBuildParticipant_Error_While_Filtering_Resources, -1,  IMarker.SEVERITY_ERROR);
          //move exceptions up to the original session, so they can be handled by the maven builder
          //XXX current exceptions refer to maven-resource-plugin (since that's what we used), we should probably 
          // throw a new exception instead to indicate the problem(s) come(s) from web resource filtering
          for(Throwable t : session.getResult().getExceptions())
          {
            getSession().getResult().addException(t);    
          }
      }
      
    } finally {
      //Restore original configuration
      copyFilteredResourcesMojo.setConfiguration(originalConfig);
      if (parentHierarchyLoaded) {
        mavenProject.setParent(null);
      }
    }
  }

  /**
   * @param configuration
   * @param extensions
   */
  private void setNonfilteredExtensions(Xpp3Dom configuration, List<Xpp3Dom> extensions) {
    if (extensions == null || extensions.isEmpty()) {
      return;
    }
    Xpp3Dom nonFilteredFileExtensionsNode = configuration.getChild("nonFilteredFileExtensions"); //$NON-NLS-1$
    if (nonFilteredFileExtensionsNode == null) {
      nonFilteredFileExtensionsNode = new Xpp3Dom("nonFilteredFileExtensions"); //$NON-NLS-1$
      configuration.addChild(nonFilteredFileExtensionsNode);
    } else {
      DomUtils.removeChildren(nonFilteredFileExtensionsNode);
    }
    
    for (Xpp3Dom ext : extensions) {
      nonFilteredFileExtensionsNode.addChild(ext);
    }
  }

  private void setValue(Xpp3Dom configuration, String childName, Object value) {
    Xpp3Dom  childNode = configuration.getChild(childName);
    if (childNode==null){
      childNode = new Xpp3Dom(childName);
      configuration.addChild(childNode);
    }
    childNode.setValue((value == null)?null:value.toString());
  }

  private void setupFilters(Xpp3Dom configuration, List<String> filters) {
    if (!filters.isEmpty()) {
      Xpp3Dom  filtersNode = configuration.getChild("filters"); //$NON-NLS-1$
      
      if (filtersNode==null){
        filtersNode = new Xpp3Dom("filters"); //$NON-NLS-1$
        configuration.addChild(filtersNode);
      } else {
        DomUtils.removeChildren(filtersNode);
      }
      
      for (String filter : filters) {
        Xpp3Dom filterNode = new Xpp3Dom("filter"); //$NON-NLS-1$
        //Workaround : when run via the BuildParticipant, the maven-resource-plugin won't 
        //find a filter defined with a relative path, so we turn it into an absolute one
        IPath filterPath = new Path(filter);
        boolean isAbsolute = false;
        if (filter.startsWith("${basedir}") ||filter.startsWith("/") || filterPath.getDevice() != null) { //$NON-NLS-1$ //$NON-NLS-2$
          isAbsolute = true;
        }
        String filterAbsolutePath;
        if (isAbsolute) {
          filterAbsolutePath = filter;
        } else {
          filterAbsolutePath = "${basedir}/"+filter; //$NON-NLS-1$
        }

        filterNode.setValue(filterAbsolutePath);
        filtersNode.addChild(filterNode );
      }
    }
  }
  
  private void setupDelimiters(Xpp3Dom configuration) {
    Xpp3Dom  useDefaultDelimitersNode = configuration.getChild("useDefaultDelimiters"); //$NON-NLS-1$
    if (useDefaultDelimitersNode==null){
      useDefaultDelimitersNode = new Xpp3Dom("useDefaultDelimiters"); //$NON-NLS-1$
      configuration.addChild(useDefaultDelimitersNode);
    }
    useDefaultDelimitersNode.setValue(Boolean.FALSE.toString());

    Xpp3Dom  delimitersNode = configuration.getChild("delimiters"); //$NON-NLS-1$
    if (delimitersNode==null){
      delimitersNode = new Xpp3Dom("delimiters"); //$NON-NLS-1$
      configuration.addChild(delimitersNode);
    } else {
      DomUtils.removeChildren(delimitersNode);
    }
    Xpp3Dom delimiter = new Xpp3Dom("delimiter"); //$NON-NLS-1$
    delimiter.setValue("${*}"); //$NON-NLS-1$
    delimitersNode.addChild(delimiter);
  }
  

  private void setupResources(Xpp3Dom configuration, List<Xpp3Dom> resources) {
    Xpp3Dom  resourcesNode = configuration.getChild("resources"); //$NON-NLS-1$
    if (resourcesNode==null){
      resourcesNode = new Xpp3Dom("resources"); //$NON-NLS-1$
      configuration.addChild(resourcesNode);
    } else {
      resourcesNode.setAttribute("default-value", ""); //$NON-NLS-1$ //$NON-NLS-2$
      DomUtils.removeChildren(resourcesNode);
    }
    for (Xpp3Dom resource : resources)
    {
      resourcesNode.addChild(resource);
    }
  }
  
  private MojoExecution getExecution(MavenExecutionPlan executionPlan, String artifactId) {
    if (executionPlan == null) return null;
    for(MojoExecution execution : executionPlan.getMojoExecutions()) {
      if(artifactId.equals(execution.getArtifactId()) ) {
        return execution;
      }
    }
    return null;
  }

  /**
   * Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=356725. 
   * Loads the parent project hierarchy if needed.
   * @param facade
   * @param monitor
   * @return true if parent projects had to be loaded.
   * @throws CoreException
   */
  private boolean loadParentHierarchy(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
    boolean loadedParent = false; 
    MavenProject mavenProject = facade.getMavenProject();
    try {
      if (mavenProject.getModel().getParent() == null || mavenProject.getParent() != null) {
        //If the method is called without error, we can assume the project has been fully loaded
        //No need to continue. 
        return false;
      }
    } catch (IllegalStateException e) {
    //The parent can not be loaded properly 
    }
    MavenExecutionRequest request = null;
    while(mavenProject !=null && mavenProject.getModel().getParent() != null) {
        if(monitor.isCanceled()) {
          break;
        }
        if (request == null) {
          request = MavenPlugin.getMavenProjectRegistry().createExecutionRequest(facade, monitor);
        }
        MavenProject parentProject = MavenPlugin.getMaven().resolveParentProject(request, mavenProject, monitor);
        if (parentProject != null) {
          mavenProject.setParent(parentProject);
          loadedParent = true;            
        }
        mavenProject = parentProject;
    }
    return loadedParent; 
  }
  
  
}
