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

import java.io.IOException;
import java.util.EnumSet;

import javax.servlet.DispatcherType;

import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;

@ManagedObject("Filter Mappings")
public class FilterMapping implements Dumpable
{
    /** Dispatch types */
    public static final int DEFAULT=0;
    public static final int REQUEST=1;
    public static final int FORWARD=2;
    public static final int INCLUDE=4;
    public static final int ERROR=8;
    public static final int ASYNC=16;
    public static final int ALL=31;


    /* ------------------------------------------------------------ */
    /** Dispatch type from name
     * @param type the type name
     * @return the dispatcher type
     */
    public static DispatcherType dispatch(String type)
    {
        if ("request".equalsIgnoreCase(type))
            return DispatcherType.REQUEST;
        if ("forward".equalsIgnoreCase(type))
            return DispatcherType.FORWARD;
        if ("include".equalsIgnoreCase(type))
            return DispatcherType.INCLUDE;
        if ("error".equalsIgnoreCase(type))
            return DispatcherType.ERROR;
        if ("async".equalsIgnoreCase(type))
            return DispatcherType.ASYNC;
        throw new IllegalArgumentException(type);
    }

    /* ------------------------------------------------------------ */
    /** Dispatch type from name
     * @param type the dispatcher type
     * @return the type constant ({@link #REQUEST}, {@link #ASYNC}, {@link #FORWARD}, {@link #INCLUDE}, or {@link #ERROR})
     */
    public static int dispatch(DispatcherType type)
    {
        switch(type)
        {
          case REQUEST:
                  return REQUEST;
          case ASYNC:
                  return ASYNC;
          case FORWARD:
                  return FORWARD;
          case INCLUDE:
                  return INCLUDE;
          case ERROR:
                  return ERROR;
        }
        throw new IllegalArgumentException(type.toString());
    }


    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */


    private int _dispatches=DEFAULT;
    private String _filterName;
    private transient FilterHolder _holder;
    private String[] _pathSpecs;
    private String[] _servletNames;

    /* ------------------------------------------------------------ */
    public FilterMapping()
    {}

    /* ------------------------------------------------------------ */
    /** Check if this filter applies to a path.
     * @param path The path to check or null to just check type
     * @param type The type of request: __REQUEST,__FORWARD,__INCLUDE, __ASYNC or __ERROR.
     * @return True if this filter applies
     */
    boolean appliesTo(String path, int type)
    {
        if (appliesTo(type))
        {
            for (int i=0;i<_pathSpecs.length;i++)
                if (_pathSpecs[i]!=null &&  PathMap.match(_pathSpecs[i], path,true))
                    return true;
        }

        return false;
    }

    /* ------------------------------------------------------------ */
    /** Check if this filter applies to a particular dispatch type.
     * @param type The type of request:
     *      {@link Handler#REQUEST}, {@link Handler#FORWARD}, {@link Handler#INCLUDE} or {@link Handler#ERROR}.
     * @return <code>true</code> if this filter applies
     */
    boolean appliesTo(int type)
    {
        if (_dispatches==0)
                return type==REQUEST || type==ASYNC && _holder.isAsyncSupported();
        return (_dispatches&type)!=0;
    }

    /* ------------------------------------------------------------ */
    public boolean appliesTo(DispatcherType t)
    {
        return appliesTo(dispatch(t));
    }
    
    /* ------------------------------------------------------------ */
    public boolean isDefaultDispatches()
    {
        return _dispatches==0;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @return Returns the filterName.
     */
    @ManagedAttribute(value="filter name", readonly=true)
    public String getFilterName()
    {
        return _filterName;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Returns the holder.
     */
    FilterHolder getFilterHolder()
    {
        return _holder;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Returns the pathSpec.
     */
    @ManagedAttribute(value="url patterns", readonly=true)
    public String[] getPathSpecs()
    {
        return _pathSpecs;
    }

    /* ------------------------------------------------------------ */
    public void setDispatcherTypes(EnumSet<DispatcherType> dispatcherTypes)
    {
        _dispatches=DEFAULT;
        if (dispatcherTypes!=null)
        {
            if (dispatcherTypes.contains(DispatcherType.ERROR))
                _dispatches|=ERROR;
            if (dispatcherTypes.contains(DispatcherType.FORWARD))
                _dispatches|=FORWARD;
            if (dispatcherTypes.contains(DispatcherType.INCLUDE))
                _dispatches|=INCLUDE;
            if (dispatcherTypes.contains(DispatcherType.REQUEST))
                _dispatches|=REQUEST;
            if (dispatcherTypes.contains(DispatcherType.ASYNC))
                _dispatches|=ASYNC;
        }
    }

    /* ------------------------------------------------------------ */
    /**
     * @param dispatches The dispatches to set.
     * @see #DEFAULT
     * @see #REQUEST
     * @see #ERROR
     * @see #FORWARD
     * @see #INCLUDE
     */
    public void setDispatches(int dispatches)
    {
        _dispatches = dispatches;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param filterName The filterName to set.
     */
    public void setFilterName(String filterName)
    {
        _filterName = filterName;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param holder The holder to set.
     */
    void setFilterHolder(FilterHolder holder)
    {
        _holder = holder;
        setFilterName(holder.getName());
    }

    /* ------------------------------------------------------------ */
    /**
     * @param pathSpecs The Path specifications to which this filter should be mapped.
     */
    public void setPathSpecs(String[] pathSpecs)
    {
        _pathSpecs = pathSpecs;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param pathSpec The pathSpec to set.
     */
    public void setPathSpec(String pathSpec)
    {
        _pathSpecs = new String[]{pathSpec};
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Returns the servletName.
     */
    @ManagedAttribute(value="servlet names", readonly=true)
    public String[] getServletNames()
    {
        return _servletNames;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param servletNames Maps the {@link #setFilterName(String) named filter} to multiple servlets
     * @see #setServletName
     */
    public void setServletNames(String[] servletNames)
    {
        _servletNames = servletNames;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param servletName Maps the {@link #setFilterName(String) named filter} to a single servlet
     * @see #setServletNames
     */
    public void setServletName(String servletName)
    {
        _servletNames = new String[]{servletName};
    }

    /* ------------------------------------------------------------ */
    public String toString()
    {
        return
        TypeUtil.asList(_pathSpecs)+"/"+
        TypeUtil.asList(_servletNames)+"=="+
        _dispatches+"=>"+
        _filterName;
    }

    /* ------------------------------------------------------------ */
    public void dump(Appendable out, String indent) throws IOException
    {
        out.append(String.valueOf(this)).append("\n");
    }

    /* ------------------------------------------------------------ */
    public String dump()
    {
        return ContainerLifeCycle.dump(this);
    }
}
