//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//


package org.eclipse.jetty.maven.plugin;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.maven.model.Plugin;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.jetty.util.StringUtil;



/**
 * WarPluginInfo
 *
 * Information about the maven-war-plugin contained in the pom
 */
public class WarPluginInfo
{
    private MavenProject _project;
    private Plugin _plugin;
    private List<String> _dependentMavenWarIncludes;
    private List<String> _dependentMavenWarExcludes;
    private List<OverlayConfig> _overlayConfigs;
    
    
    
    /**
     * @param project
     */
    public WarPluginInfo (MavenProject project)
    {
        _project = project;
    }

    
    
    
    /**
     * Find the maven-war-plugin, if one is configured
     * @return
     */
    public Plugin getPlugin()
    {
        if (_plugin == null)
        {
            List plugins = _project.getBuildPlugins();
            if (plugins == null)
                return null;


            Iterator itor = plugins.iterator();
            while (itor.hasNext() && _plugin==null)
            {
                Plugin plugin = (Plugin)itor.next();
                if ("maven-war-plugin".equals(plugin.getArtifactId()))
                    _plugin = plugin;
            }
        }
        return _plugin;
    }

    
    

    /**
     * Get value of dependentWarIncludes for maven-war-plugin
     * @return
     */
    public List<String> getDependentMavenWarIncludes()
    {
        if (_dependentMavenWarIncludes == null)
        {
            getPlugin();

            if (_plugin == null)
                return null;

            Xpp3Dom node = (Xpp3Dom)_plugin.getConfiguration();
            if (node == null)
                return null;

            node = node.getChild("dependentWarIncludes");
            if (node == null)
                return null;
            String val = node.getValue();
            _dependentMavenWarIncludes = StringUtil.csvSplit(null,val,0,val.length());
        }
        return _dependentMavenWarIncludes;
    }


    
    
    /**
     * Get value of dependentWarExcludes for maven-war-plugin
     * @return
     */
    public List<String> getDependentMavenWarExcludes()
    {
        if (_dependentMavenWarExcludes == null)
        {
            getPlugin();

            if (_plugin == null)
                return null;

            Xpp3Dom node = (Xpp3Dom)_plugin.getConfiguration();
            if (node == null)
                return null;

            node = node.getChild("dependentWarExcludes");
            if (node == null)
                return null;
            String val = node.getValue();
            _dependentMavenWarExcludes = StringUtil.csvSplit(null,val,0,val.length());
        }
        return _dependentMavenWarExcludes;
    }

    
    
    
    /**
     * Get config for any overlays that have been declared for the maven-war-plugin.
     * 
     * @return
     */
    public List<OverlayConfig> getMavenWarOverlayConfigs ()
    {
        if (_overlayConfigs == null)
        {
            getPlugin();

            if (_plugin == null)
                return Collections.emptyList();

            getDependentMavenWarIncludes();
            getDependentMavenWarExcludes();

            Xpp3Dom node = (Xpp3Dom)_plugin.getConfiguration();
            if (node == null)
                return Collections.emptyList();

            node = node.getChild("overlays");
            if (node == null)
                return Collections.emptyList();

            Xpp3Dom[] nodes = node.getChildren("overlay");
            if (nodes == null)
                return Collections.emptyList();

            _overlayConfigs = new ArrayList<OverlayConfig>();
            for (int i=0;i<nodes.length;i++)
            {
                OverlayConfig overlayConfig = new OverlayConfig(nodes[i], _dependentMavenWarIncludes, _dependentMavenWarExcludes);
                _overlayConfigs.add(overlayConfig);
            }
        }

        return _overlayConfigs;
    }
    
    
    
    
    /**
     * @return the xml as a string
     */
    public String getMavenWarOverlayConfigAsString ()
    {
        getPlugin();

        if (_plugin == null)
            return "";
        
        Xpp3Dom node = (Xpp3Dom)_plugin.getConfiguration();
        if (node == null)
            return "";
        return node.toString();
    }
}
