//
//  ========================================================================
//  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.plus.annotation;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletContainerInitializer;

import org.eclipse.jetty.util.ConcurrentHashSet;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.webapp.WebAppContext;

public class ContainerInitializer
{
    private static final Logger LOG = Log.getLogger(ContainerInitializer.class);
    
    final protected ServletContainerInitializer _target;
    final protected Class<?>[] _interestedTypes;
    final protected Set<String> _applicableTypeNames = new ConcurrentHashSet<String>();
    final protected Set<String> _annotatedTypeNames = new ConcurrentHashSet<String>();


    public ContainerInitializer (ServletContainerInitializer target, Class<?>[] classes)
    {
        _target = target;
        _interestedTypes = classes;
    }
    
    public ContainerInitializer (ClassLoader loader, String toString)
    {
        Matcher m = Pattern.compile("ContainerInitializer\\{(.*),interested=(.*),applicable=(.*),annotated=(.*)\\}").matcher(toString);
        if (!m.matches())
            throw new IllegalArgumentException(toString);

        try
        {
            _target = (ServletContainerInitializer)loader.loadClass(m.group(1)).newInstance();
            String[] interested = StringUtil.arrayFromString(m.group(2));
            _interestedTypes = new Class<?>[interested.length];
            for (int i=0;i<interested.length;i++)
                _interestedTypes[i]=loader.loadClass(interested[i]);
            for (String s:StringUtil.arrayFromString(m.group(3)))
                _applicableTypeNames.add(s);
            for (String s:StringUtil.arrayFromString(m.group(4)))
                _annotatedTypeNames.add(s);
        }
        catch(Exception e)
        {
            throw new IllegalArgumentException(toString, e);
        }
    }
    
    public ServletContainerInitializer getTarget ()
    {
        return _target;
    }

    public Class[] getInterestedTypes ()
    {
        return _interestedTypes;
    }


    /**
     * A class has been found that has an annotation of interest
     * to this initializer.
     * @param className the class name to add
     */
    public void addAnnotatedTypeName (String className)
    {
        _annotatedTypeNames.add(className);
    }

    public Set<String> getAnnotatedTypeNames ()
    {
        return Collections.unmodifiableSet(_annotatedTypeNames);
    }

    public void addApplicableTypeName (String className)
    {
        _applicableTypeNames.add(className);
    }

    public Set<String> getApplicableTypeNames ()
    {
        return Collections.unmodifiableSet(_applicableTypeNames);
    }


    public void callStartup(WebAppContext context)
    throws Exception
    {
        if (_target != null)
        {
            Set<Class<?>> classes = new HashSet<Class<?>>();

            ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader(context.getClassLoader());

            try
            {
                for (String s : _applicableTypeNames)
                    classes.add(Loader.loadClass(context.getClass(), s));

                context.getServletContext().setExtendedListenerTypes(true);
                if (LOG.isDebugEnabled())
                {
                    long start = System.nanoTime();
                    _target.onStartup(classes, context.getServletContext());
                    LOG.debug("ContainerInitializer {} called in {}ms", _target.getClass().getName(), TimeUnit.MILLISECONDS.convert(System.nanoTime()-start, TimeUnit.NANOSECONDS));
                }
                else
                    _target.onStartup(classes, context.getServletContext());
            }
            finally
            { 
                context.getServletContext().setExtendedListenerTypes(false);
                Thread.currentThread().setContextClassLoader(oldLoader);
            }
        }
    }

    public String toString()
    {
        List<String> interested = Collections.emptyList();
        if (_interestedTypes != null)
        {
            interested = new ArrayList<>(_interestedTypes.length);
            for (Class<?> c : _interestedTypes)
                interested.add(c.getName());
        }

        return String.format("ContainerInitializer{%s,interested=%s,applicable=%s,annotated=%s}",_target.getClass().getName(),interested,_applicableTypeNames,_annotatedTypeNames);
    }

    public void resolveClasses(WebAppContext context, Map<String, Set<String>> classMap) 
    {
        //We have already found the classes that directly have an annotation that was in the HandlesTypes
        //annotation of the ServletContainerInitializer. For each of those classes, walk the inheritance
        //hierarchy to find classes that extend or implement them.
        Set<String> annotatedClassNames = getAnnotatedTypeNames();
        if (annotatedClassNames != null && !annotatedClassNames.isEmpty())
        {
            for (String name : annotatedClassNames)
            {
                //add the class that has the annotation
                addApplicableTypeName(name);

                //find and add the classes that inherit the annotation               
                addInheritedTypes(classMap, (Set<String>)classMap.get(name));
            }
        }


        //Now we need to look at the HandlesTypes classes that were not annotations. We need to
        //find all classes that extend or implement them.
        if (getInterestedTypes() != null)
        {
            for (Class<?> c : getInterestedTypes())
            {
                if (!c.isAnnotation())
                {
                    //find and add the classes that implement or extend the class.
                    //but not including the class itself
                    addInheritedTypes(classMap, (Set<String>)classMap.get(c.getName()));
                }
            }
        }
    }

    private void addInheritedTypes(Map<String, Set<String>> classMap,Set<String> names)
    {
        if (names == null || names.isEmpty())
            return;

        for (String s : names)
        {
            //add the name of the class
            addApplicableTypeName(s);

            //walk the hierarchy and find all types that extend or implement the class
            addInheritedTypes(classMap, (Set<String>)classMap.get(s));
        }
    }
}
