/*******************************************************************************
 * Copyright (c) 2008-2015 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 java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.war.Overlay;
import org.apache.maven.plugin.war.overlay.InvalidOverlayConfigurationException;
import org.apache.maven.plugin.war.overlay.OverlayManager;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils;
import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.internal.markers.SourceLocation;
import org.eclipse.m2e.core.internal.markers.SourceLocationHelper;
import org.eclipse.m2e.wtp.internal.Messages;
import org.eclipse.m2e.wtp.internal.StringUtils;
import org.eclipse.m2e.wtp.namemapping.FileNameMapping;
import org.eclipse.m2e.wtp.namemapping.PatternBasedFileNameMapping;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
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;


/**
 *  maven-war-plugin configuration model.
 *  
 * @see <a href="http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html">http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html</a>
 *  
 * @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>.
 * 
 * @author Igor Fedorenko
 * @author Fred Bricon
 */
@SuppressWarnings("restriction")
public class WarPluginConfiguration extends AbstractFilteringSupportMavenPlugin implements IMavenPackageFilter {

  private static final Logger LOG = LoggerFactory.getLogger(WarPluginConfiguration.class);
  
  private static final String WAR_SOURCE_FOLDER = "/src/main/webapp"; //$NON-NLS-1$

  private static final String WAR_PACKAGING = "war"; //$NON-NLS-1$

  private static final String WEB_XML = "WEB-INF/web.xml"; //$NON-NLS-1$

  private static final int WEB_3_1_ID = 31;

  private static final String WEB_3_1_TEXT = "3.1"; //$NON-NLS-1$
  
  //Keep backward compat with WTP < Kepler
  private static final IProjectFacetVersion WEB_31 = WebFacetUtils.WEB_FACET.hasVersion(WEB_3_1_TEXT)?
                                                              WebFacetUtils.WEB_FACET.getVersion(WEB_3_1_TEXT)
                                                             :WebFacetUtils.WEB_30;
  
  private IProject project;
  
  private MavenProject mavenProject;

  public WarPluginConfiguration(MavenProject mavenProject, IProject project) {
    this.project = project;
    this.mavenProject = mavenProject;
    Plugin plugin = getPlugin();
    if (plugin != null) {
    	setConfiguration((Xpp3Dom)plugin.getConfiguration());
    }
  }

  public Plugin getPlugin() {
    return mavenProject.getPlugin("org.apache.maven.plugins:maven-war-plugin"); //$NON-NLS-1$
  }

  static boolean isWarProject(MavenProject mavenProject) {
    return WAR_PACKAGING.equals(mavenProject.getPackaging());
  }

  public Xpp3Dom[] getWebResources() {
    Xpp3Dom config = getConfiguration();
    if(config != null) {
      Xpp3Dom webResources = config.getChild("webResources"); //$NON-NLS-1$
      if (webResources != null && webResources.getChildCount() > 0)
      {
        int count = webResources.getChildCount();  
        Xpp3Dom[] resources = new Xpp3Dom[count];
        for (int i= 0; i< count ; i++) {
          //MECLIPSEWTP-97 support old maven-war-plugin configurations which used <webResource> 
          // instead of <resource>
          Xpp3Dom webResource = new Xpp3Dom(webResources.getChild(i),"resource");  //$NON-NLS-1$
          
          //MECLIPSEWTP-152 : Web resource processing fails when targetPath has a leading /
          Xpp3Dom targetPath = webResource.getChild("targetPath"); //$NON-NLS-1$
          if(targetPath != null && targetPath.getValue() != null && targetPath.getValue().startsWith("/")) { //$NON-NLS-1$
            targetPath.setValue(targetPath.getValue().substring(1));
          }

          resources[i] = webResource;
        }
        return resources;
      }
    }
    return new Xpp3Dom[0];
  }

  public String getWarSourceDirectory() {
    Xpp3Dom dom = getConfiguration();
    if(dom == null) {
      return WAR_SOURCE_FOLDER;
    }

    Xpp3Dom[] warSourceDirectory = dom.getChildren("warSourceDirectory"); //$NON-NLS-1$
    if(warSourceDirectory != null && warSourceDirectory.length > 0) {
      // first one wins
      String dir = warSourceDirectory[0].getValue();
      //MNGECLIPSE-1600 fixed absolute warSourceDirectory thanks to Snjezana Peco's patch
      if(project != null) {
        return WTPProjectsUtil.tryProjectRelativePath(project, dir).toOSString();
      }
      return dir;
    }

    return WAR_SOURCE_FOLDER;
  }

  @Override
public String[] getPackagingExcludes() {
    return DomUtils.getPatternsAsArray(getConfiguration(),"packagingExcludes"); //$NON-NLS-1$
  }

  @Override
public String[] getPackagingIncludes() {
    return DomUtils.getPatternsAsArray(getConfiguration(),"packagingIncludes"); //$NON-NLS-1$
  }

  @Override
public String[] getSourceExcludes() {
    return DomUtils.getPatternsAsArray(getConfiguration(),"warSourceExcludes"); //$NON-NLS-1$
  }

  @Override
public String[] getSourceIncludes() {
    return DomUtils.getPatternsAsArray(getConfiguration(),"warSourceIncludes"); //$NON-NLS-1$
  }

  public boolean isAddManifestClasspath() {
    Xpp3Dom config = getConfiguration();
    if(config != null) {
      Xpp3Dom arch = config.getChild("archive"); //$NON-NLS-1$
      if(arch != null) {
        Xpp3Dom manifest = arch.getChild("manifest"); //$NON-NLS-1$
        if(manifest != null) {
          Xpp3Dom addToClp = manifest.getChild("addClasspath"); //$NON-NLS-1$
          if(addToClp != null) {
            return Boolean.valueOf(addToClp.getValue());
          }
        }
      }
  }
    return false;
  }

  public String getManifestClasspathPrefix() {
    Xpp3Dom config = getConfiguration();
    if(config != null) {
      Xpp3Dom arch = config.getChild("archive"); //$NON-NLS-1$
      if(arch != null) {
        Xpp3Dom manifest = arch.getChild("manifest"); //$NON-NLS-1$
        if(manifest != null) {
          Xpp3Dom prefix = manifest.getChild("classpathPrefix"); //$NON-NLS-1$
          if(prefix != null && !StringUtils.nullOrEmpty(prefix.getValue())) {
            String rawPrefix = prefix.getValue().trim();
            if (!rawPrefix.endsWith("/")){ //$NON-NLS-1$
              rawPrefix += "/"; //$NON-NLS-1$
            }
            return rawPrefix;
          }
        }
      }
    }
    return null;
  }

  public IProjectFacetVersion getWebFacetVersion(IProject project) {
    IFile webXml;
    String customWebXml = getCustomWebXml(project);
    if (customWebXml == null) {
      webXml = project.getFolder(getWarSourceDirectory()).getFile(WEB_XML);
    } else {
      webXml = project.getFile(customWebXml);
    }

    if(webXml.isAccessible()) {
      try {
        InputStream is = webXml.getContents();
        try {
          JavaEEQuickPeek jqp = new JavaEEQuickPeek(is);
          switch(jqp.getVersion()) {
            case J2EEVersionConstants.WEB_2_2_ID:
              return WebFacetUtils.WEB_22;
            case J2EEVersionConstants.WEB_2_3_ID:
              return WebFacetUtils.WEB_23;
            case J2EEVersionConstants.WEB_2_4_ID:
              return WebFacetUtils.WEB_24;
            case J2EEVersionConstants.WEB_2_5_ID:
              return WebFacetUtils.WEB_25;
            case J2EEVersionConstants.WEB_3_0_ID:
              return WebFacetUtils.WEB_30;
            case WEB_3_1_ID:
              return WEB_31;
          }
        } finally {
          is.close();
        }
      } catch(IOException ex) {
        // expected
      } catch(CoreException ex) {
        // expected
      }
    }
   
    //If no web.xml found and the project depends on some java EE 7 jar, then set web facet to 3.1
    if (WTPProjectsUtil.hasInClassPath(project, "javax.servlet.http.WebConnection")) { //$NON-NLS-1$
      return WEB_31;
    }
    //MNGECLIPSE-1978 If no web.xml found and the project depends on some java EE 6 jar, then set web facet to 3.0
    if (WTPProjectsUtil.hasInClassPath(project, "javax.servlet.annotation.WebServlet")) { //$NON-NLS-1$
      return WebFacetUtils.WEB_30;
    }
    
    //If no web.xml found, don't change existing facet version
    try {
      IFacetedProject fProject = ProjectFacetsManager.create(project);
      if (fProject != null && fProject.hasProjectFacet(WebFacetUtils.WEB_FACET)) {
        return fProject.getProjectFacetVersion(WebFacetUtils.WEB_FACET);
      }
    } catch (Exception e) {
      LOG.warn(NLS.bind(Messages.Error_Reading_Project_Facet, project.getName()), e); 
    }
    
    //MNGECLIPSE-984 web.xml is optional for 2.5 Web Projects
    return WTPProjectsUtil.DEFAULT_WEB_FACET;
    //We don't want to prevent the project creation when the java compiler level is < 5, we coud try that instead :
    //IProjectFacetVersion javaFv = JavaFacetUtils.compilerLevelToFacet(JavaFacetUtils.getCompilerLevel(project));
    //return (JavaFacetUtils.JAVA_50.compareTo(javaFv) > 0)?WebFacetUtils.WEB_24:WebFacetUtils.WEB_25; 
  }
  /**
   * Get the custom location of web.xml, as set in &lt;webXml&gt;.
   * @return the custom location of web.xml or null if &lt;webXml&gt; is not set
   */
  public String getCustomWebXml(IProject project) {
    Xpp3Dom config = getConfiguration();
    if(config != null) {
      Xpp3Dom webXmlDom = config.getChild("webXml"); //$NON-NLS-1$
      if(webXmlDom != null && webXmlDom.getValue() != null) {
        String webXmlFile = webXmlDom.getValue().trim();
        webXmlFile = ProjectUtils.getRelativePath(project, webXmlFile);
        return webXmlFile;
      }
    }
    return null;
  }

  /**
   * @return
   * @throws CoreException 
   */
  public List<Overlay> getOverlays() throws CoreException {
    Overlay currentProjectOverlay = Overlay.createInstance();
    currentProjectOverlay.setArtifact(mavenProject.getArtifact());
    OverlayManager overlayManager = null;
    List<Overlay> overlays = null;
    try {
      overlayManager = new OverlayManager(getConfiguredOverlays(), 
                                                         mavenProject, 
                                                         getDependentWarIncludes(),
                                                         getDependentWarExcludes(), 
                                                         currentProjectOverlay);
      overlays = overlayManager.getOverlays();
    } catch(InvalidOverlayConfigurationException ex) {
      throw new CoreException(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, ex.getMessage(),ex));
    }
    
    return overlays;
  }
  
  public String getDependentWarIncludes() {
    return DomUtils.getChildValue(getConfiguration(), "dependentWarIncludes", "**/**"); //$NON-NLS-1$ //$NON-NLS-2$
  }

  public String getDependentWarExcludes() {
    return DomUtils.getChildValue(getConfiguration(), "dependentWarExcludes", "META-INF/MANIFEST.MF"); //$NON-NLS-1$ //$NON-NLS-2$
  }

  public List<Overlay> getConfiguredOverlays() {
    Xpp3Dom config = getConfiguration();
    if(config != null) {
      Xpp3Dom overlaysNode = config.getChild("overlays"); //$NON-NLS-1$
      if (overlaysNode != null && overlaysNode.getChildCount() > 0) {
        List<Overlay> overlays = new ArrayList<>(overlaysNode.getChildCount());
        for (Xpp3Dom overlayNode : overlaysNode.getChildren("overlay")) { //$NON-NLS-1$
          overlays.add(parseOverlay(overlayNode));
        }
        return overlays;
      }
    }
    return Collections.emptyList();
  }
  
  /**
   * @param overlayNode
   * @return
   */
  private Overlay parseOverlay(Xpp3Dom overlayNode) {
    String artifactId = DomUtils.getChildValue(overlayNode, "artifactId"); //$NON-NLS-1$
    String groupId = DomUtils.getChildValue(overlayNode, "groupId"); //$NON-NLS-1$
    String[] exclusions = DomUtils.getChildrenAsStringArray(overlayNode.getChild("excludes"), "exclude"); //$NON-NLS-1$ //$NON-NLS-2$
    String[] inclusions = DomUtils.getChildrenAsStringArray(overlayNode.getChild("includes"), "include"); //$NON-NLS-1$ //$NON-NLS-2$
    String classifier = DomUtils.getChildValue(overlayNode, "classifier"); //$NON-NLS-1$
    boolean filtered = DomUtils.getBooleanChildValue(overlayNode, "filtered"); //$NON-NLS-1$
    boolean skip = DomUtils.getBooleanChildValue(overlayNode, "skip"); //$NON-NLS-1$
    String type = DomUtils.getChildValue(overlayNode, "type", "war"); //$NON-NLS-1$ //$NON-NLS-2$
    String targetPath = DomUtils.getChildValue(overlayNode, "targetPath", "/"); //$NON-NLS-1$ //$NON-NLS-2$

    Overlay overlay = new Overlay();
    overlay.setArtifactId(artifactId);
    overlay.setGroupId(groupId);
    overlay.setClassifier(classifier);
    if (exclusions== null || exclusions.length ==0) {
      overlay.setExcludes(getDependentWarExcludes());
    } else {
      overlay.setExcludes(exclusions);
    }
    if (inclusions== null || inclusions.length ==0) {
      overlay.setIncludes(getDependentWarIncludes());
    } else {
      overlay.setIncludes(inclusions);
    }
    overlay.setFiltered(filtered);
    overlay.setSkip(skip);
    overlay.setTargetPath(targetPath);
    overlay.setType(type);
    
    return overlay;
  }

  public FileNameMapping getFileNameMapping() {
    Xpp3Dom config = getConfiguration();
    String expression = null;
    if(config != null) {
      expression = DomUtils.getChildValue(config, "outputFileNameMapping"); //$NON-NLS-1$
    }
    return new PatternBasedFileNameMapping(expression);
  }
  
  @Override
protected String getFilteringAttribute() {
    return "filteringDeploymentDescriptors"; //$NON-NLS-1$
  }
  
  public String getWarName() {
    Xpp3Dom config = getConfiguration();
    String warName = null;
    if (config != null) {
      warName = DomUtils.getChildValue(config, "warName"); //$NON-NLS-1$
    }
    if (StringUtils.nullOrEmpty(warName)) {
      warName = mavenProject.getBuild().getFinalName();
    }
    return warName;
  }

  @Override
  public SourceLocation getSourceLocation() {
    Plugin plugin = getPlugin();
    if (plugin == null) {
      return null;
    }
    return SourceLocationHelper.findLocation(plugin, "configuration"); //$NON-NLS-1$
  }

  @Override
  public String getSourceIncludeParameterName() {
    return "warSourceIncludes"; //$NON-NLS-1$
  }

  
  public boolean isFailOnMissingWebXml() {
    Xpp3Dom config = getConfiguration();
    boolean failOnMissingWebXml = true;
    if (config != null) {
    	failOnMissingWebXml = DomUtils.getBooleanChildValue(config, "failOnMissingWebXml", true); //$NON-NLS-1$
    };
    return failOnMissingWebXml;
  }
}
