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

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;


/* ------------------------------------------------------------ */
/**
 * ClasspathPattern performs sequential pattern matching of a class name 
 * against an internal array of classpath pattern entries.
 * 
 * When an entry starts with '-' (minus), reverse matching is performed.
 * When an entry ends with '.' (period), prefix matching is performed.
 * 
 * When class is initialized from a classpath pattern string, entries 
 * in this string should be separated by ':' (semicolon) or ',' (comma).
 */

public class ClasspathPattern
{
    private static class Entry
    {
        public String classpath = null;
        public boolean result = false;
        public boolean partial = false;      
    }
    
    final private List<String> _patterns = new ArrayList<String>();
    final private List<Entry> _entries = new ArrayList<Entry>();
    
    /* ------------------------------------------------------------ */
    public ClasspathPattern()
    {
    }
    
    /* ------------------------------------------------------------ */
    public ClasspathPattern(String[] patterns)
    {
        setPatterns(patterns);
    }
    
    /* ------------------------------------------------------------ */
    public ClasspathPattern(String pattern)
    {
        setPattern(pattern);
    }
    

    /* ------------------------------------------------------------ */
    /**
     * Initialize the matcher by parsing each classpath pattern in an array
     * 
     * @param patterns array of classpath patterns
     */
    private void setPatterns(String[] patterns)
    {
        _patterns.clear();
        _entries.clear();
        addPatterns(patterns);
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @param patterns array of classpath patterns
     */
    private void addPatterns(String[] patterns)
    {
        if (patterns != null)
        {
            Entry entry = null; 
            for (String pattern : patterns)
            {
                entry = createEntry(pattern);
                if (entry != null) 
                {
                    _patterns.add(pattern);
                    _entries.add(entry);
                }
            }
        }
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @param patterns array of classpath patterns
     */
    private void prependPatterns(String[] patterns)
    {
        if (patterns != null)
        {
            Entry entry = null;
            int i=0;
            for (String pattern : patterns)
            {
                entry = createEntry(pattern);
                if (entry != null) 
                {
                    _patterns.add(i,pattern);
                    _entries.add(i,entry);
                    i++;
                }
            }
        }
    }
    
    /* ------------------------------------------------------------ */
    /**
     * Create an entry object containing information about 
     * a single classpath pattern
     * 
     * @param pattern single classpath pattern
     * @return corresponding Entry object
     */
    private Entry createEntry(String pattern)
    {
        Entry entry = null;
        
        if (pattern != null)
        {
            String item = pattern.trim();
            if (item.length() > 0)
            {
                entry = new Entry();
                entry.result = !item.startsWith("-");
                entry.partial = item.endsWith(".");
                entry.classpath = entry.result ? item : item.substring(1).trim();
            }
        }
        return entry;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * Initialize the matcher by parsing a classpath pattern string
     * 
     * @param pattern classpath pattern string
     */
    public void setPattern(String pattern)
    {
        _patterns.clear();
        _entries.clear();
        addPattern(pattern);
    }

    /* ------------------------------------------------------------ */
    /**
     * Parse a classpath pattern string and appending the result
     * to the existing configuration.
     * 
     * @param pattern classpath pattern string
     */
    public void addPattern(String pattern)
    {
        ArrayList<String> patterns = new ArrayList<String>();
        StringTokenizer entries = new StringTokenizer(pattern, ":,");
        while (entries.hasMoreTokens())
        {
            patterns.add(entries.nextToken());
        }
        
        addPatterns(patterns.toArray(new String[patterns.size()]));
    }   
    

    /* ------------------------------------------------------------ */
    public void prependPattern(String classOrPackage)
    {
        ArrayList<String> patterns = new ArrayList<String>();
        StringTokenizer entries = new StringTokenizer(classOrPackage, ":,");
        while (entries.hasMoreTokens())
        {
            patterns.add(entries.nextToken());
        }
        
        prependPatterns(patterns.toArray(new String[patterns.size()]));
    }
    
    
    /* ------------------------------------------------------------ */
    /**
     * @return array of classpath patterns
     */
    public String[] getPatterns()
    {
        String[] patterns = null;
        
        if (_patterns!=null && _patterns.size() > 0)
        {
            patterns = _patterns.toArray(new String[_patterns.size()]);
        }
        
        return patterns;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * Match the class name against the pattern
     *
     * @param name name of the class to match
     * @return true if class matches the pattern
     */
    public boolean match(String name)
    {       
        boolean result=false;

        if (_entries != null)
        {
            name = name.replace('/','.');

            int startIndex = 0;

            while(startIndex < name.length() && name.charAt(startIndex) == '.') {
                startIndex++;
            }

            int dollar = name.indexOf("$");

            int endIndex =  dollar != -1 ? dollar : name.length();

            for (Entry entry : _entries)
            {
                if (entry != null)
                {               
                    if (entry.partial)
                    {
                        if (name.regionMatches(startIndex, entry.classpath, 0, entry.classpath.length()))
                        {
                            result = entry.result;
                            break;
                        }
                    }
                    else
                    {
                        int regionLength = endIndex-startIndex;
                        if (regionLength == entry.classpath.length()
                                && name.regionMatches(startIndex, entry.classpath, 0, regionLength))
                        {
                            result = entry.result;
                            break;
                        }
                    }
                }
            }
        }
        return result;
    }

}
