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

import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.function.Predicate;

import org.eclipse.jetty.util.ArrayTernaryTrie;
import org.eclipse.jetty.util.Trie;
import org.eclipse.jetty.util.URIUtil;

/** 
 * URI path map to Object.
 * <p>
 * This mapping implements the path specification recommended
 * in the 2.2 Servlet API.
 * </p>
 *
 * <p>
 * Path specifications can be of the following forms:
 * </p>
 * <pre>
 * /foo/bar           - an exact path specification.
 * /foo/*             - a prefix path specification (must end '/*').
 * *.ext              - a suffix path specification.
 * /                  - the default path specification.
 * ""                 - the / path specification
 * </pre>
 * 
 * Matching is performed in the following order 
 * <ol>
 * <li>Exact match.</li>
 * <li>Longest prefix match.</li>
 * <li>Longest suffix match.</li>
 * <li>default.</li>
 * </ol>
 * 
 * <p>
 * Multiple path specifications can be mapped by providing a list of
 * specifications. By default this class uses characters ":," as path
 * separators, unless configured differently by calling the static
 * method @see PathMap#setPathSpecSeparators(String)
 * <p>
 * Special characters within paths such as '?� and ';' are not treated specially
 * as it is assumed they would have been either encoded in the original URL or
 * stripped from the path.
 * <p>
 * This class is not synchronized.  If concurrent modifications are
 * possible then it should be synchronized at a higher level.
 * 
 * @param <O> the Map.Entry value type
 * @deprecated replaced with {@link org.eclipse.jetty.http.pathmap.PathMappings} (this class will be removed in Jetty 10) 
 */
@Deprecated
public class PathMap<O> extends HashMap<String,O>
{
    /* ------------------------------------------------------------ */
    private static String __pathSpecSeparators = ":,";

    /* ------------------------------------------------------------ */
    /** Set the path spec separator.
     * Multiple path specification may be included in a single string
     * if they are separated by the characters set in this string.
     * By default this class uses ":," characters as path separators.
     * @param s separators
     */
    public static void setPathSpecSeparators(String s)
    {
        __pathSpecSeparators=s;
    }

    /* --------------------------------------------------------------- */
    Trie<MappedEntry<O>> _prefixMap=new ArrayTernaryTrie<>(false);
    Trie<MappedEntry<O>> _suffixMap=new ArrayTernaryTrie<>(false);
    final Map<String,MappedEntry<O>> _exactMap=new HashMap<>();

    List<MappedEntry<O>> _defaultSingletonList=null;
    MappedEntry<O> _prefixDefault=null;
    MappedEntry<O> _default=null;
    boolean _nodefault=false;

    /* --------------------------------------------------------------- */
    public PathMap()
    {
        this(11);
    }

    /* --------------------------------------------------------------- */
    public PathMap(boolean noDefault)
    {
        this(11, noDefault);
    }

    /* --------------------------------------------------------------- */
    public PathMap(int capacity)
    {
        this(capacity, false);
    }

    /* --------------------------------------------------------------- */
    private PathMap(int capacity, boolean noDefault)
    {
        super(capacity);
        _nodefault=noDefault;
    }

    /* --------------------------------------------------------------- */
    /** 
     * Construct from dictionary PathMap.
     * @param dictMap the map representing the dictionary to build this PathMap from
     */
    public PathMap(Map<String, ? extends O> dictMap)
    {
        putAll(dictMap);
    }

    /* --------------------------------------------------------------- */
    /** Add a single path match to the PathMap.
     * @param pathSpec The path specification, or comma separated list of
     * path specifications.
     * @param object The object the path maps to
     */
    @Override
    public O put(String pathSpec, O object)
    {
        if ("".equals(pathSpec.trim()))
        {
            MappedEntry<O> entry = new MappedEntry<>("",object);
            entry.setMapped("");
            _exactMap.put("", entry);
            return super.put("", object);
        }

        StringTokenizer tok = new StringTokenizer(pathSpec,__pathSpecSeparators);
        O old =null;

        while (tok.hasMoreTokens())
        {
            String spec=tok.nextToken();

            if (!spec.startsWith("/") && !spec.startsWith("*."))
                throw new IllegalArgumentException("PathSpec "+spec+". must start with '/' or '*.'");

            old = super.put(spec,object);

            // Make entry that was just created.
            MappedEntry<O> entry = new MappedEntry<>(spec,object);

            if (entry.getKey().equals(spec))
            {
                if (spec.equals("/*"))
                    _prefixDefault=entry;
                else if (spec.endsWith("/*"))
                {
                    String mapped=spec.substring(0,spec.length()-2);
                    entry.setMapped(mapped);
                    while (!_prefixMap.put(mapped,entry))
                        _prefixMap=new ArrayTernaryTrie<>((ArrayTernaryTrie<MappedEntry<O>>)_prefixMap,1.5);
                }
                else if (spec.startsWith("*."))
                {
                    String suffix=spec.substring(2);
                    while(!_suffixMap.put(suffix,entry))
                        _suffixMap=new ArrayTernaryTrie<>((ArrayTernaryTrie<MappedEntry<O>>)_suffixMap,1.5);
                }
                else if (spec.equals(URIUtil.SLASH))
                {
                    if (_nodefault)
                        _exactMap.put(spec,entry);
                    else
                    {
                        _default=entry;
                        _defaultSingletonList=Collections.singletonList(_default);
                    }
                }
                else
                {
                    entry.setMapped(spec);
                    _exactMap.put(spec,entry);
                }
            }
        }

        return old;
    }

    /* ------------------------------------------------------------ */
    /** Get object matched by the path.
     * @param path the path.
     * @return Best matched object or null.
     */
    public O match(String path)
    {
        MappedEntry<O> entry = getMatch(path);
        if (entry!=null)
            return entry.getValue();
        return null;
    }


    /* --------------------------------------------------------------- */
    /** Get the entry mapped by the best specification.
     * @param path the path.
     * @return Map.Entry of the best matched  or null.
     */
    public MappedEntry<O> getMatch(String path)
    {
        if (path==null)
            return null;

        int l=path.length();

        MappedEntry<O> entry=null;

        //special case
        if (l == 1 && path.charAt(0)=='/')
        {
            entry = _exactMap.get("");
            if (entry != null)
                return entry;
        }

        // try exact match
        entry=_exactMap.get(path);
        if (entry!=null)
            return entry;

        // prefix search
        int i=l;
        final Trie<PathMap.MappedEntry<O>> prefix_map=_prefixMap;
        while(i>=0)
        {
            entry=prefix_map.getBest(path,0,i);
            if (entry==null)
                break;
            String key = entry.getKey();
            if (key.length()-2>=path.length() || path.charAt(key.length()-2)=='/')
                return entry;
            i=key.length()-3;
        }

        // Prefix Default
        if (_prefixDefault!=null)
            return _prefixDefault;

        // Extension search
        i=0;
        final Trie<PathMap.MappedEntry<O>> suffix_map=_suffixMap;
        while ((i=path.indexOf('.',i+1))>0)
        {
            entry=suffix_map.get(path,i+1,l-i-1);
            if (entry!=null)
                return entry;
        }

        // Default
        return _default;
    }

    /* --------------------------------------------------------------- */
    /** Get all entries matched by the path.
     * Best match first.
     * @param path Path to match
     * @return List of Map.Entry instances key=pathSpec
     */
    public List<? extends Map.Entry<String,O>> getMatches(String path)
    {
        MappedEntry<O> entry;
        List<MappedEntry<O>> entries=new ArrayList<>();

        if (path==null)
            return entries;
        if (path.length()==0)
            return _defaultSingletonList;

        // try exact match
        entry=_exactMap.get(path);
        if (entry!=null)
            entries.add(entry);

        // prefix search
        int l=path.length();
        int i=l;
        final Trie<PathMap.MappedEntry<O>> prefix_map=_prefixMap;
        while(i>=0)
        {
            entry=prefix_map.getBest(path,0,i);
            if (entry==null)
                break;
            String key = entry.getKey();
            if (key.length()-2>=path.length() || path.charAt(key.length()-2)=='/')
                entries.add(entry);

            i=key.length()-3;
        }

        // Prefix Default
        if (_prefixDefault!=null)
            entries.add(_prefixDefault);

        // Extension search
        i=0;
        final Trie<PathMap.MappedEntry<O>> suffix_map=_suffixMap;
        while ((i=path.indexOf('.',i+1))>0)
        {
            entry=suffix_map.get(path,i+1,l-i-1);
            if (entry!=null)
                entries.add(entry);
        }

        // root match
        if ("/".equals(path))
        {
            entry=_exactMap.get("");
            if (entry!=null)
                entries.add(entry);
        }
            
        // Default
        if (_default!=null)
            entries.add(_default);

        return entries;
    }


    /* --------------------------------------------------------------- */
    /** Return whether the path matches any entries in the PathMap,
     * excluding the default entry
     * @param path Path to match
     * @return Whether the PathMap contains any entries that match this
     */
    public boolean containsMatch(String path)
    {
        MappedEntry<?> match = getMatch(path);
        return match!=null && !match.equals(_default);
    }

    /* --------------------------------------------------------------- */
    @Override
    public O remove(Object pathSpec)
    {
        if (pathSpec!=null)
        {
            String spec=(String) pathSpec;
            if (spec.equals("/*"))
                _prefixDefault=null;
            else if (spec.endsWith("/*"))
                _prefixMap.remove(spec.substring(0,spec.length()-2));
            else if (spec.startsWith("*."))
                _suffixMap.remove(spec.substring(2));
            else if (spec.equals(URIUtil.SLASH))
            {
                _default=null;
                _defaultSingletonList=null;
            }
            else
                _exactMap.remove(spec);
        }
        return super.remove(pathSpec);
    }

    /* --------------------------------------------------------------- */
    @Override
    public void clear()
    {
        _exactMap.clear();
        _prefixMap=new ArrayTernaryTrie<>(false);
        _suffixMap=new ArrayTernaryTrie<>(false);
        _default=null;
        _defaultSingletonList=null;
        _prefixDefault=null;
        super.clear();
    }

    /* --------------------------------------------------------------- */
    /**
     * @param pathSpec the path spec
     * @param path the path
     * @return true if match.
     */
    public static boolean match(String pathSpec, String path)
    {
        return match(pathSpec, path, false);
    }

    /* --------------------------------------------------------------- */
    /**
     * @param pathSpec the path spec
     * @param path the path
     * @param noDefault true to not handle the default path "/" special, false to allow matcher rules to run  
     * @return true if match.
     */
    public static boolean match(String pathSpec, String path, boolean noDefault)
    {
        if (pathSpec.length()==0)
            return "/".equals(path);
            
        char c = pathSpec.charAt(0);
        if (c=='/')
        {
            if (!noDefault && pathSpec.length()==1 || pathSpec.equals(path))
                return true;

            if(isPathWildcardMatch(pathSpec, path))
                return true;
        }
        else if (c=='*')
            return path.regionMatches(path.length()-pathSpec.length()+1,
                    pathSpec,1,pathSpec.length()-1);
        return false;
    }

    /* --------------------------------------------------------------- */
    private static boolean isPathWildcardMatch(String pathSpec, String path)
    {
        // For a spec of "/foo/*" match "/foo" , "/foo/..." but not "/foobar"
        int cpl=pathSpec.length()-2;
        if (pathSpec.endsWith("/*") && path.regionMatches(0,pathSpec,0,cpl))
        {
            if (path.length()==cpl || '/'==path.charAt(cpl))
                return true;
        }
        return false;
    }


    /* --------------------------------------------------------------- */
    /** Return the portion of a path that matches a path spec.
     * @param pathSpec the path spec
     * @param path the path
     * @return null if no match at all.
     */
    public static String pathMatch(String pathSpec, String path)
    {
        char c = pathSpec.charAt(0);

        if (c=='/')
        {
            if (pathSpec.length()==1)
                return path;

            if (pathSpec.equals(path))
                return path;

            if (isPathWildcardMatch(pathSpec, path))
                return path.substring(0,pathSpec.length()-2);
        }
        else if (c=='*')
        {
            if (path.regionMatches(path.length()-(pathSpec.length()-1),
                    pathSpec,1,pathSpec.length()-1))
                return path;
        }
        return null;
    }

    /* --------------------------------------------------------------- */
    /** Return the portion of a path that is after a path spec.
     * @param pathSpec the path spec
     * @param path the path
     * @return The path info string
     */
    public static String pathInfo(String pathSpec, String path)
    {
        if ("".equals(pathSpec))
            return path; //servlet 3 spec sec 12.2 will be '/'

        char c = pathSpec.charAt(0);

        if (c=='/')
        {
            if (pathSpec.length()==1)
                return null;

            boolean wildcard = isPathWildcardMatch(pathSpec, path);

            // handle the case where pathSpec uses a wildcard and path info is "/*"
            if (pathSpec.equals(path) && !wildcard)
                return null;

            if (wildcard)
            {
                if (path.length()==pathSpec.length()-2)
                    return null;
                return path.substring(pathSpec.length()-2);
            }
        }
        return null;
    }


    /* ------------------------------------------------------------ */
    /** Relative path.
     * @param base The base the path is relative to.
     * @param pathSpec The spec of the path segment to ignore.
     * @param path the additional path
     * @return base plus path with pathspec removed
     */
    public static String relativePath(String base,
            String pathSpec,
            String path )
    {
        String info=pathInfo(pathSpec,path);
        if (info==null)
            info=path;

        if( info.startsWith( "./"))
            info = info.substring( 2);
        if( base.endsWith( URIUtil.SLASH))
            if( info.startsWith( URIUtil.SLASH))
                path = base + info.substring(1);
            else
                path = base + info;
        else
            if( info.startsWith( URIUtil.SLASH))
                path = base + info;
            else
                path = base + URIUtil.SLASH + info;
        return path;
    }

    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    public static class MappedEntry<O> implements Map.Entry<String,O>
    {
        private final String key;
        private final O value;
        private String mapped;

        MappedEntry(String key, O value)
        {
            this.key=key;
            this.value=value;
        }

        @Override
        public String getKey()
        {
            return key;
        }

        @Override
        public O getValue()
        {
            return value;
        }

        @Override
        public O setValue(O o)
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public String toString()
        {
            return key+"="+value;
        }

        public String getMapped()
        {
            return mapped;
        }

        void setMapped(String mapped)
        {
            this.mapped = mapped;
        }
    }
    
    public static class PathSet extends AbstractSet<String> implements Predicate<String>
    {
        private final PathMap<Boolean> _map = new PathMap<>();
        
        @Override
        public Iterator<String> iterator()
        {
            return _map.keySet().iterator();
        }

        @Override
        public int size()
        {
            return _map.size();
        }
        
        @Override
        public boolean add(String item)
        {
            return _map.put(item,Boolean.TRUE)==null;
        }
        
        @Override
        public boolean remove(Object item)
        {
            return _map.remove(item)!=null;
        }

        @Override
        public boolean contains(Object o) 
        { 
            return _map.containsKey(o); 
        }
        
        @Override
        public boolean test(String s)
        {
            return _map.containsMatch(s);
        }
        
        public boolean containsMatch(String s) 
        { 
            return _map.containsMatch(s); 
        }
    }
}
