//
//  ========================================================================
//  Copyright (c) 1995-2012 Sabre Holdings.
//  ------------------------------------------------------------------------
//  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.ant;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.jar.Manifest;

import javax.servlet.Servlet;

import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.ant.types.Attribute;
import org.eclipse.jetty.ant.types.Attributes;
import org.eclipse.jetty.ant.types.FileMatchingConfiguration;
import org.eclipse.jetty.ant.utils.TaskLog;
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.FilterMapping;
import org.eclipse.jetty.servlet.Holder;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlet.ServletMapping;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.FragmentConfiguration;
import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
import org.eclipse.jetty.webapp.MetaInfConfiguration;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.webapp.WebInfConfiguration;
import org.eclipse.jetty.webapp.WebXmlConfiguration;
import org.eclipse.jetty.xml.XmlConfiguration;



/**
 * AntWebAppContext
 * 
 * Extension of WebAppContext to allow configuration via Ant environment.
 *
 */
public class AntWebAppContext extends WebAppContext
{
    private static final Logger LOG = Log.getLogger(WebAppContext.class);
    
    public final AntWebInfConfiguration antWebInfConfiguration = new AntWebInfConfiguration();
    public final WebXmlConfiguration webXmlConfiguration = new WebXmlConfiguration();
    public final MetaInfConfiguration metaInfConfiguration = new MetaInfConfiguration();
    public final FragmentConfiguration fragmentConfiguration = new FragmentConfiguration();
    public final EnvConfiguration envConfiguration = new EnvConfiguration();
    public final PlusConfiguration plusConfiguration = new PlusConfiguration();
    public final AnnotationConfiguration annotationConfiguration = new AnnotationConfiguration();
    public final JettyWebXmlConfiguration jettyWebXmlConfiguration = new JettyWebXmlConfiguration();


    public final Configuration[] DEFAULT_CONFIGURATIONS = 
        { 
         antWebInfConfiguration,
         webXmlConfiguration,
         metaInfConfiguration,
         fragmentConfiguration,
         envConfiguration,
         plusConfiguration,
         annotationConfiguration,
         jettyWebXmlConfiguration
        };
    

    public final static String DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN =
    ".*/.*jsp-api-[^/]*\\.jar$|.*/.*jsp-[^/]*\\.jar$|.*/.*taglibs[^/]*\\.jar$|.*/.*jstl[^/]*\\.jar$|.*/.*jsf-impl-[^/]*\\.jar$|.*/.*javax.faces-[^/]*\\.jar$|.*/.*myfaces-impl-[^/]*\\.jar$";


    /** Location of jetty-env.xml file. */
    private File jettyEnvXml;
    
    /** List of web application libraries. */
    private List libraries = new ArrayList();

    /** List of web application class directories. */
    private List classes = new ArrayList();
    
    /** context xml file to apply to the webapp */
    private File contextXml;
    
    /** List of extra scan targets for this web application. */
    private FileSet scanTargets;
    
    /** context attributes to set **/
    private Attributes attributes;
    
    private Project project;
    
    private List<File> scanFiles;
    


    /** Extra scan targets. */
    private FileMatchingConfiguration extraScanTargetsConfiguration;


    private FileMatchingConfiguration librariesConfiguration;
    

    public static void dump(ClassLoader loader)
    {
        while (loader != null)
        {
            System.err.println(loader);
            if (loader instanceof URLClassLoader)
            {
                URL[] urls = ((URLClassLoader)loader).getURLs();
                if (urls != null)
                {
                    for (URL u:urls)
                        System.err.println("\t"+u+"\n");
                }
            }
            loader = loader.getParent();
        }
    }

    
    /**
     * AntURLClassLoader
     *
     * Adapt the AntClassLoader which is not a URLClassLoader - this is needed for
     * jsp to be able to search the classpath.
     */
    public static class AntURLClassLoader extends URLClassLoader
    {
        private AntClassLoader antLoader;
        
        public AntURLClassLoader(AntClassLoader antLoader)
        {
            super(new URL[] {}, antLoader);
            this.antLoader = antLoader;      
        }

        @Override
        public InputStream getResourceAsStream(String name)
        {
            return super.getResourceAsStream(name);
        }

        @Override
        public void close() throws IOException
        {
            super.close();
        }

        @Override
        protected void addURL(URL url)
        {
            super.addURL(url);
        }

        @Override
        public URL[] getURLs()
        {
            Set<URL> urls = new HashSet<URL>();
            
            //convert urls from antLoader
            String[] paths = antLoader.getClasspath().split(new String(new char[]{File.pathSeparatorChar}));
            if (paths != null)
            {
                for (String p:paths)
                {
                    File f = new File(p);
                    try
                    {
                        urls.add(f.toURI().toURL());   
                    }
                    catch (Exception e)
                    {
                        LOG.ignore(e);
                    }
                }
            }
            
            //add in any that may have been added to us as a URL directly
            URL[] ourURLS = super.getURLs();
            if (ourURLS != null)
            {
                for (URL u:ourURLS)
                    urls.add(u);
            }
            
            return urls.toArray(new URL[urls.size()]);
        }

        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException
        {
            return super.findClass(name);
        }

        @Override
        protected Package definePackage(String name, Manifest man, URL url) throws IllegalArgumentException
        {
            return super.definePackage(name, man, url);
        }

        @Override
        public URL findResource(String name)
        {
            return super.findResource(name);
        }

        @Override
        public Enumeration<URL> findResources(String name) throws IOException
        {
            return super.findResources(name);
        }

        @Override
        protected PermissionCollection getPermissions(CodeSource codesource)
        {
            return super.getPermissions(codesource);
        }

        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException
        {
            return super.loadClass(name);
        }

        @Override
        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
        {
            return super.loadClass(name, resolve);
        }

        @Override
        protected Object getClassLoadingLock(String className)
        {
            return super.getClassLoadingLock(className);
        }

        @Override
        public URL getResource(String name)
        {
            return super.getResource(name);
        }

        @Override
        public Enumeration<URL> getResources(String name) throws IOException
        {
            return super.getResources(name);
        }

        @Override
        protected Package definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion,
                                        String implVendor, URL sealBase) throws IllegalArgumentException
        {
            return super.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);
        }

        @Override
        protected Package getPackage(String name)
        {
            return super.getPackage(name);
        }

        @Override
        protected Package[] getPackages()
        {
            return super.getPackages();
        }

        @Override
        protected String findLibrary(String libname)
        {
            return super.findLibrary(libname);
        }

        @Override
        public void setDefaultAssertionStatus(boolean enabled)
        {
            super.setDefaultAssertionStatus(enabled);
        }

        @Override
        public void setPackageAssertionStatus(String packageName, boolean enabled)
        {
            super.setPackageAssertionStatus(packageName, enabled);
        }

        @Override
        public void setClassAssertionStatus(String className, boolean enabled)
        {
            super.setClassAssertionStatus(className, enabled);
        }

        @Override
        public void clearAssertionStatus()
        {
            super.clearAssertionStatus();
        }
    }
    
    
    /**
     * AntServletHolder
     *
     *
     */
    public static class AntServletHolder extends ServletHolder
    {

        public AntServletHolder()
        {
            super();
        }


        public AntServletHolder(Class<? extends Servlet> servlet)
        {
            super(servlet);
        }


        public AntServletHolder(Servlet servlet)
        {
            super(servlet);
        }


        public AntServletHolder(String name, Class<? extends Servlet> servlet)
        {
            super(name, servlet);
        }


        public AntServletHolder(String name, Servlet servlet)
        {
            super(name, servlet);
        }

        protected String getSystemClassPath (ClassLoader loader) throws Exception
        {
            StringBuilder classpath=new StringBuilder();
            while (loader != null)
            {
                if (loader instanceof URLClassLoader)
                {
                    URL[] urls = ((URLClassLoader)loader).getURLs();
                    if (urls != null)
                    {
                        for (int i=0;i<urls.length;i++)
                        {
                            Resource resource = Resource.newResource(urls[i]);
                            File file=resource.getFile();
                            if (file!=null && file.exists())
                            {
                                if (classpath.length()>0)
                                    classpath.append(File.pathSeparatorChar);
                                classpath.append(file.getAbsolutePath());
                            }
                        }
                    }
                }
                else if (loader instanceof AntClassLoader)
                {
                    classpath.append(((AntClassLoader)loader).getClasspath());
                }

                loader = loader.getParent();
            }

            return classpath.toString();
        }

    }

    
    
    /**
     * AntServletHandler
     *
     *
     */
    public static class AntServletHandler extends ServletHandler
    {

        @Override
        public ServletHolder newServletHolder(Holder.Source source)
        {
            return new AntServletHolder();
        }

    }



    /**
     * Default constructor. Takes project as an argument
     *
     * @param project the project.
     */
    public AntWebAppContext(Project project) throws Exception
    {
        super();
        this.project = project;
        setConfigurations(DEFAULT_CONFIGURATIONS);
        setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN);
        setParentLoaderPriority(true);
    }
    

    /**
     * Adds a new Ant's attributes tag object if it have not been created yet.
     */
    public void addAttributes(Attributes atts)
    {
        if (this.attributes != null)
        {
            throw new BuildException("Only one <attributes> tag is allowed!");
        }

        this.attributes = atts;
    }

    
    public void addLib(FileSet lib)
    {
        libraries.add(lib);
    }


    public void addClasses(FileSet classes)
    {
        this.classes.add(classes);
    }
    
    

    @Override
    protected ServletHandler newServletHandler()
    {
        return new AntServletHandler();
    }


    public void setJettyEnvXml(File jettyEnvXml)
    {
        this.jettyEnvXml = jettyEnvXml;
        TaskLog.log("jetty-env.xml file: = " + (jettyEnvXml == null ? null : jettyEnvXml.getAbsolutePath()));
    }

    public File getJettyEnvXml ()
    {
        return this.jettyEnvXml;
    }

    


    public List getLibraries()
    {
        return librariesConfiguration.getBaseDirectories();
    }

 
    public void addScanTargets(FileSet scanTargets)
    {
        if (this.scanTargets != null)
        {
            throw new BuildException("Only one <scanTargets> tag is allowed!");
        }

        this.scanTargets = scanTargets;
    }
    
    public List getScanTargetFiles () 
    {
        if (this.scanTargets == null)
            return null;
        
      
        FileMatchingConfiguration configuration = new FileMatchingConfiguration();
        configuration.addDirectoryScanner(scanTargets.getDirectoryScanner(project));
        return configuration.getBaseDirectories();
    }
    
    public List<File> getScanFiles()
    {
        if (scanFiles == null)
            scanFiles = initScanFiles();
        return scanFiles;
    }
    
    
    public boolean isScanned (File file)
    {
       List<File> files = getScanFiles();
       if (files == null || files.isEmpty())
           return false;
       return files.contains(file);
    }
    
    
    public List<File> initScanFiles ()
    {
        List<File> scanList = new ArrayList<File>();
        
        if (getDescriptor() != null)
        {
            try (Resource r = Resource.newResource(getDescriptor());)
            {
                scanList.add(r.getFile());
            }
            catch (IOException e)
            {
                throw new BuildException(e);
            }
        }

        if (getJettyEnvXml() != null)
        {
            try (Resource r = Resource.newResource(getJettyEnvXml());)
            {
                scanList.add(r.getFile());
            }
            catch (IOException e)
            {
                throw new BuildException("Problem configuring scanner for jetty-env.xml", e);
            }
        }

        if (getDefaultsDescriptor() != null)
        {
            try (Resource r = Resource.newResource(getDefaultsDescriptor());)
            {
                if (!WebAppContext.WEB_DEFAULTS_XML.equals(getDefaultsDescriptor()))
                {   
                    scanList.add(r.getFile());
                }
            }
            catch (IOException e)
            {
                throw new BuildException("Problem configuring scanner for webdefaults.xml", e);
            }
        }

        if (getOverrideDescriptor() != null)
        {
            try
            {
                Resource r = Resource.newResource(getOverrideDescriptor());
                scanList.add(r.getFile());
            }
            catch (IOException e)
            {
                throw new BuildException("Problem configuring scanner for webdefaults.xml", e);
            }
        }

        //add any extra classpath and libs 
        List<File> cpFiles = getClassPathFiles();
        if (cpFiles != null)
            scanList.addAll(cpFiles);
        
        //any extra scan targets
        @SuppressWarnings("unchecked")
        List<File> scanFiles = (List<File>)getScanTargetFiles();
        if (scanFiles != null)
            scanList.addAll(scanFiles);
        
        return scanList;
    }
    
    
    
    @Override
    public void setWar(String path)
    {
        super.setWar(path);

        try
        {
            Resource war = Resource.newResource(path);
            if (war.exists() && war.isDirectory() && getDescriptor() == null)
            {
                Resource webXml = war.addPath("WEB-INF/web.xml");
                setDescriptor(webXml.toString());
            }
        }
        catch (IOException e)
        {
            throw new BuildException(e);
        }
    }


    /**
     * 
     */
    public void doStart()
    {
        try
        {
            TaskLog.logWithTimestamp("Starting web application "+this.getDescriptor());
            if (jettyEnvXml != null && jettyEnvXml.exists())
                envConfiguration.setJettyEnvXml(Resource.toURL(jettyEnvXml));
            
            ClassLoader parentLoader = this.getClass().getClassLoader();
            if (parentLoader instanceof AntClassLoader)
                parentLoader = new AntURLClassLoader((AntClassLoader)parentLoader);

            setClassLoader(new WebAppClassLoader(parentLoader, this));
            if (attributes != null && attributes.getAttributes() != null)
            {
                for (Attribute a:attributes.getAttributes())
                    setAttribute(a.getName(), a.getValue());
            }
            
            //apply a context xml file if one was supplied
            if (contextXml != null)
            {
                XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(contextXml));
                TaskLog.log("Applying context xml file "+contextXml);
                xmlConfiguration.configure(this);   
            }
            
            super.doStart();
        }
        catch (Exception e)
        {
            TaskLog.log(e.toString());
        }
    }

    public void doStop()
    {
        try
        {
            scanFiles = null;
            TaskLog.logWithTimestamp("Stopping web application "+this);
            Thread.currentThread().sleep(500L);
            super.doStop();
            //remove all filters, servlets and listeners. They will be recreated
            //either via application of a context xml file or web.xml or annotation or servlet api
            setEventListeners(new EventListener[0]);
            getServletHandler().setFilters(new FilterHolder[0]);
            getServletHandler().setFilterMappings(new FilterMapping[0]);
            getServletHandler().setServlets(new ServletHolder[0]);
            getServletHandler().setServletMappings(new ServletMapping[0]);
        }
        catch (InterruptedException e)
        {
            TaskLog.log(e.toString());
        }
        catch (Exception e)
        {
            TaskLog.log(e.toString());
        }
    }


    
    /**
     * @return a list of classpath files (libraries and class directories).
     */
    public List<File> getClassPathFiles()
    {
        List<File> classPathFiles = new ArrayList<File>();
        Iterator classesIterator = classes.iterator();
        while (classesIterator.hasNext())
        {
            FileSet clazz = (FileSet) classesIterator.next();
            classPathFiles.add(clazz.getDirectoryScanner(project).getBasedir());
        }

        Iterator iterator = libraries.iterator();
        while (iterator.hasNext())
        {
            FileSet library = (FileSet) iterator.next();
            String[] includedFiles = library.getDirectoryScanner(project).getIncludedFiles();
            File baseDir = library.getDirectoryScanner(project).getBasedir();

            for (int i = 0; i < includedFiles.length; i++)
            {
                classPathFiles.add(new File(baseDir, includedFiles[i]));
            }
        }


        return classPathFiles;
    }

    
    /**
     * @return a <code>FileMatchingConfiguration</code> object describing the
     *         configuration of all libraries added to this particular web app
     *         (both classes and libraries).
     */
    public FileMatchingConfiguration getLibrariesConfiguration()
    {
        FileMatchingConfiguration config = new FileMatchingConfiguration();

        Iterator classesIterator = classes.iterator();
        while (classesIterator.hasNext())
        {
            FileSet clazz = (FileSet) classesIterator.next();
            config.addDirectoryScanner(clazz.getDirectoryScanner(project));
        }

        Iterator librariesIterator = libraries.iterator();
        while (librariesIterator.hasNext())
        {
            FileSet library = (FileSet) librariesIterator.next();
            config.addDirectoryScanner(library.getDirectoryScanner(project));
        }

        return config;
    }


    public File getContextXml()
    {
        return contextXml;
    }


    public void setContextXml(File contextXml)
    {
        this.contextXml = contextXml;
    }
    
}
