/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you under the Apache License, Version 2.0 (the            *
 * "License"); you may not use this file except in compliance   *
 * with the License.  You may obtain a copy of the License at   *
 *                                                              *
 *   http://www.apache.org/licenses/LICENSE-2.0                 *
 *                                                              *
 * Unless required by applicable law or agreed to in writing,   *
 * software distributed under the License is distributed on an  *
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
 * KIND, either express or implied.  See the License for the    *
 * specific language governing permissions and limitations      *
 * under the License.                                           *
 ****************************************************************/

package org.apache.jsieve.comparators;

import org.apache.jsieve.*;
import org.apache.jsieve.exception.LookupException;
import org.apache.jsieve.exception.SieveException;
import org.apache.jsieve.exception.SievePatternException;

import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * Class ComparatorUtils implements utility methods used by Comparators.
 */
public class ComparatorUtils implements MatchTypeTags {

    /**
     * Constructor for ComparatorUtils.
     */
    private ComparatorUtils() {
        super();
    }

    /**
     * Method <code>match</code> answers a boolean indicating if the parameter
     * <code>matchTarget</code> compares to parameter
     * <code>matchArgument</code> is a match of <code>matchType</code> using
     * the comparator <code>comparatorName</code>.
     * 
     * @param comparatorName
     * @param matchType
     * @param matchArgument
     * @param matchTarget
     * @return boolean
     */
    public static boolean match(String comparatorName, String matchType,
            String matchTarget, String matchArgument) throws SieveException {
        boolean isMatched = false;
        if (matchType.equals(IS_TAG))
            isMatched = is(comparatorName, matchTarget, matchArgument);
        else if (matchType.equals(CONTAINS_TAG))
            isMatched = contains(comparatorName, matchTarget, matchArgument);
        else if (matchType.equals(MATCHES_TAG))
            isMatched = matches(comparatorName, matchTarget, matchArgument);
        return isMatched;
    }

    /**
     * <p>
     * Method <code>matches</code> answers a boolean indicating if the
     * parameter <code>string</code> matches the glob pattern described by
     * parameter <code>glob</code>.
     * 
     * @param string
     * @param glob
     * @return boolean
     * @throws SievePatternException
     */
    static public boolean matches(String string, String glob)
            throws SievePatternException {
        // TODO Is there a way to re-use the compiled pattern?
        try {
            String regex = sieveToJavaRegex(glob);
            System.err.println(regex);
            return Pattern.compile(regex, Pattern.CASE_INSENSITIVE).matcher(
                    string).matches();
        } catch (PatternSyntaxException e) {
            throw new SievePatternException(e.getMessage());
        }
    }

    /**
     * <p>
     * Method <code>contains</code> answers a boolean indicating if the
     * parameter <code>container</code> contains the parameter
     * <code>contents</code>.
     * </p>
     * 
     * @param container
     * @param contents
     * @return boolean
     */
    static public boolean contains(String container, String contents) {
        return container.indexOf(contents) > -1;
    }

    /**
     * <p>
     * Method <code>equals</code> answers a boolean indicating if the
     * parameter <code>string1</code> is equal to the parameter
     * <code>string2</code>.
     * </p>
     * 
     * @param string1
     * @param string2
     * @return boolean
     */
    static public boolean equals(String string1, String string2) {
        return string1.equals(string2);
    }

    /**
     * Returns true if the char is a special char for regex
     */
    private static boolean isRegexSpecialChar(char ch) {
        return (ch == '*' || ch == '?' || ch == '+' || ch == '[' || ch == ']'
                || ch == '(' || ch == ')' || ch == '|' || ch == '^'
                || ch == '$' || ch == '.' || ch == '{' || ch == '}' || ch == '\\');
    }

    /**
     * Returns true if the char is a special char for sieve matching
     */
    private static boolean isSieveMatcherSpecialChar(char ch) {
        return (ch == '*' || ch == '?' || ch == '\\');
    }

    /**
     * Converts a Sieve pattern in a java regex pattern
     */
    public static String sieveToJavaRegex(String pattern) {
        int ch;
        StringBuffer buffer = new StringBuffer(2 * pattern.length());
        for (ch = 0; ch < pattern.length(); ch++) {
            switch (pattern.charAt(ch)) {
            case '*':
                buffer.append(".*");
                break;
            case '?':
                buffer.append('.');
                break;
            case '\\':
                buffer.append('\\');
                if (ch == pattern.length() - 1)
                    buffer.append('\\');
                else if (isSieveMatcherSpecialChar(pattern.charAt(ch + 1)))
                    buffer.append(pattern.charAt(++ch));
                else
                    buffer.append('\\');
                break;
            default:
                if (isRegexSpecialChar(pattern.charAt(ch)))
                    buffer.append('\\');
                buffer.append(pattern.charAt(ch));
                break;
            }
        }
        return buffer.toString();
    }

    /**
     * Method <code>contains<code> answers a boolean indicating if the parameter 
     * <code>container</code> contains the parameter <code>contents</code> using an
     * instance of <code>comparatorName</code>.
     * @param comparatorName
     * @param container
     * @param contents
     * @return boolean
     */
    public static boolean contains(String comparatorName, String container,
            String contents) throws LookupException {
        Contains comparatorObj = ComparatorManager.getInstance().newInstance(
                comparatorName);
        return comparatorObj.contains(container, contents);
    }

    /**
     * Method <code>is<code> answers a boolean indicating if the parameter 
     * <code>container</code> is equal to the parameter <code>contents</code> using 
     * an instance of <code>comparatorName</code>.
     * @param comparatorName
     * @param string1
     * @param string2
     * @return boolean
     */
    public static boolean is(String comparatorName, String string1,
            String string2) throws LookupException {
        Equals comparatorObj = ComparatorManager.getInstance().newInstance(
                comparatorName);
        return comparatorObj.equals(string1, string2);
    }

    /**
     * Method <code>matches</code> answers a boolean indicating if the
     * parameter
     * <code>string/code> is matched by the patterm <code>glob</code> using an
     * instance of <code>comparatorName</code>.
     * @param comparatorName
     * @param string
     * @param glob
     * @return boolean
     */
    public static boolean matches(String comparatorName, String string,
            String glob) throws SieveException {
        Matches comparatorObj = ComparatorManager.getInstance().newInstance(
                comparatorName);
        return comparatorObj.matches(string, glob);
    }

}

@@ -3293,47 +3293,8 @@
 b);%0A
-            System.err.println(regex);%0A
     

Remove debug output