/*
 * Copyright (c) 2006, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation
//
package org.eclipse.persistence.jpa.jpql;

import java.util.regex.Pattern;

/**
 * A utility class containing various methods related to the Hermes parser.
 * <p>
 * Provisional API: This interface is part of an interim API that is still under development and
 * expected to change significantly before reaching stability. It is available at this early stage
 * to solicit feedback from pioneering adopters on the understanding that any code that uses this
 * API will almost certainly be broken (repeatedly) as the API evolves.
 *
 * @version 2.6
 * @since 2.3
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public final class ExpressionTools {

    /**
     * The {@link Pattern} representing the regular expression of a numerical value as a double.
     */
    public static final Pattern DOUBLE_REGEXP = Pattern.compile("^[-+]?[0-9]*(\\.[0-9]+)?([dD]|([eE][-+]?[0-9]+))?$");

    /**
     * The constant of an empty array.
     */
    public static final Object[] EMPTY_ARRAY = new Object[0];

    /**
     * The constant for an empty string.
     */
    public static final String EMPTY_STRING = "";

    /**
     * The constant of an empty String array.
     */
    public static final String[] EMPTY_STRING_ARRAY = new String[0];

    /**
     * The {@link Pattern} representing the regular expression of a numerical value as a float.
     */
    public static final Pattern FLOAT_REGEXP = Pattern.compile("^[-+]?[0-9]*(\\.[0-9]+)?[fF]$");

    /**
     * The {@link Pattern} representing the regular expression of a numerical value as an integer.
     */
    public static final Pattern INTEGER_REGEXP = Pattern.compile("^[-+]?[0-9]+$");

    /**
     * The {@link Pattern} representing the regular expression of a numerical value as a long.
     */
    public static final Pattern LONG_REGEXP = Pattern.compile("^[-+]?[0-9]+[lL]?$");

    /**
     * ExpressionTools cannot be instantiated.
     */
    private ExpressionTools() {
        super();
        throw new IllegalAccessError("ExpressionTools cannot be instantiated");
    }

    /**
     * Converts the escape characters contained in the given {@link CharSequence} to their literal
     * representation. For example, '\b' is converted to '\\b'.
     *
     * @param value The sequence of characters to convert any escape character
     * @param position This is a one element array that needs to be adjusted when an escape
     * character is converted
     * @return The new sequence of characters that does not contain any escape character but it's
     * literal representation
     */
    public static String escape(CharSequence value, int[] position) {

        StringBuilder sb = new StringBuilder(value.length());
        int originalPosition = position[0];

        for (int index = 0, count = value.length(); index < count; index++) {
            char character = value.charAt(index);

            switch (character) {
                case '\b': sb.append("\\b");  if (index < originalPosition) position[0]++; break;
                case '\t': sb.append("\\t");  if (index < originalPosition) position[0]++; break;
                case '\n': sb.append("\\n");  if (index < originalPosition) position[0]++; break;
                case '\f': sb.append("\\f");  if (index < originalPosition) position[0]++; break;
                case '\r': sb.append("\\r");  if (index < originalPosition) position[0]++; break;
                case '\"': sb.append("\\\""); if (index < originalPosition) position[0]++; break;
                case '\\': sb.append("\\\\"); if (index < originalPosition) position[0]++; break;
                case '\0': sb.append("\\0");  if (index < originalPosition) position[0]++; break;
                case '\1': sb.append("\\1");  if (index < originalPosition) position[0]++; break;
                case '\2': sb.append("\\2");  if (index < originalPosition) position[0]++; break;
                case '\3': sb.append("\\3");  if (index < originalPosition) position[0]++; break;
                case '\4': sb.append("\\4");  if (index < originalPosition) position[0]++; break;
                case '\5': sb.append("\\5");  if (index < originalPosition) position[0]++; break;
                case '\6': sb.append("\\6");  if (index < originalPosition) position[0]++; break;
                case '\7': sb.append("\\7");  if (index < originalPosition) position[0]++; break;
                default:   sb.append(character);
            }
        }

        return sb.toString();
    }

    /**
     * Determines whether the JPQL fragment is an expression of the form <code>&lt;IDENTIFIER&gt;(</code>.
     *
     * @param wordParser The text to parse based on the current position of the cursor
     * @param identifier The identifier to verify if it's for an expression or for possibly for a
     * variable name
     * @return <code>true</code> if the identifier is followed by '('; <code>false</code> otherwise
     */
    public static boolean isFunctionExpression(WordParser wordParser, String identifier) {

        // Skip the identifier
        int count = identifier.length();
        wordParser.moveForward(identifier);

        // Check to see if ( is following the identifier
        int whitespace = wordParser.skipLeadingWhitespace();
        boolean function = wordParser.startsWith('(');

        // Revert the changes
        wordParser.moveBackward(count + whitespace);

        return function;
    }

    /**
     * Determines whether the given character should be escaped when being part of a string, i.e.
     * '\r' should be "\\r".
     *
     * @param character The character to check if it can directly be used in a string or should be escaped
     * @return <code>true</code> if the given character cannot be used directly in a string
     * @since 2.5
     */
    public static boolean isJavaEscapedCharacter(char character) {

        switch (character) {
            case '\b':
            case '\t':
            case '\n':
            case '\f':
            case '\r':
            case '\"':
            case '\\':
            case '\0':
            case '\1':
            case '\2':
            case '\3':
            case '\4':
            case '\5':
            case '\6':
            case '\7': return true;
            default:   return false;
        }
    }

    /**
     * Determines whether the given character is the character used to identify an input parameter,
     * either a named parameter or position parameter.
     *
     * @param character The character to check if it's a parameter
     * @return <code>true</code> if the given character is either : or ?; <code>false</code> otherwise
     */
    public static boolean isParameter(char character) {
        return character == ':' ||
               character == '?';
    }

    /**
     * Determines whether the given character is the single or double quote.
     *
     * @param character The character to check if it's a quote
     * @return <code>true</code> if the given character is either ' or "; <code>false</code> otherwise
     */
    public static boolean isQuote(char character) {
        return character == '\'' ||
               character == '\"';
    }

    /**
     * Returns the given string literal by wrapping it with single quotes. Any single quote within
     * the string will be escaped with another single quote.
     *
     * @param text The original text to quote
     * @return The quoted text
     * @since 2.4
     */
    public static String quote(String text) {
        text = text.replace("'", "''");
        text = "'" + text + "'";
        return text;
    }

    /**
     * Adjusts the positions contained by the given array of either one or two elements, which is
     * based on the given <em>query1</em>, by translating those positions to be at the equivalent
     * position within <em>query2</em>.
     * <p>
     * <b>Important:</b> The two JPQL queries should contain the same characters but the amount of
     * whitespace can differ. One cannot have the escape characters and the other one has the Unicode
     * characters.
     *
     * @param query1 The query where the positions are pointing
     * @param positions An array of either one or two elements positioned within <em>query1</em>
     * @param query2 The query for which the positions might need adjustment
     * @since 2.5
     */
    public static void reposition(CharSequence query1, int[] positions, CharSequence query2) {

        // Nothing to adjust
        if ((positions[0] <= 0) && (positions.length == 1)) {
            return;
        }

        int queryLength1 = query1.length();
        int queryLength2 = query2.length();

        // Queries 1 and 2 have the same length, no translation required
        if (queryLength1 == queryLength2) {
            return;
        }

        int index1 = 0;
        int index2 = 0;
        boolean position1Done = false;
        boolean position2Done = false;

        while ((index1 < queryLength1) && (index2 < queryLength2) && (!position1Done || !position2Done)) {

            char character1 = Character.toUpperCase(query1.charAt(index1));
            char character2 = Character.toUpperCase(query2.charAt(index2));

            boolean whitespace1 = Character.isWhitespace(character1);
            boolean whitespace2 = Character.isWhitespace(character2);

            if (character1 != character2) {

                // Query 2 does not have a whitespace but query 1 does
                if (whitespace1 && !whitespace2) {
                    index1++;

                    if (!position1Done) {
                        positions[0]--;
                    }

                    if (!position2Done && (positions.length > 1)) {
                        positions[1]--;
                    }
                }
                // Query 1 does not have a whitespace but the query 2 does
                else if (!whitespace1 && whitespace2) {
                    index2++;

                    if (!position1Done) {
                        positions[0]++;
                    }

                    if (!position2Done && (positions.length > 1)) {
                        positions[1]++;
                    }
                }
                // Continue with the next character
                else {
                    index1++;
                    index2++;
                }
            }
            // Continue with the next character
            else {
                index1++;
                index2++;
            }

            // Check to see if the position has been fully updated
            if ((!whitespace1 && !whitespace2) || (queryLength1 > queryLength2)) {

                if (positions[0] <= index2) {
                    position1Done = true;
                }

                if ((positions.length > 1) && positions[1] <= index2) {
                    position2Done = true;
                }
            }
        }

        // Make sure the positions are not outside of length of query2
        positions[0] = Math.min(positions[0], queryLength2);
        positions[0] = Math.max(positions[0], 0);

        if (positions.length > 1) {
            positions[1] = Math.min(positions[1], queryLength2);
            positions[1] = Math.max(positions[1], 0);
        }
    }

    /**
     * Adjusts the position, which is based on the given <em>query1</em>, by translating it to be at
     * the equivalent position within <em>query2</em>.
     * <p>
     * <b>Important:</b> The two JPQL queries should contain the same characters but the amount of
     * whitespace can differ. One cannot have the escape characters and the other one has the Unicode
     * characters.
     *
     * @param query1 The query where the positions are pointing
     * @param position1 The position of a cursor within <em>query1</em>
     * @param query2 The query for which the position might need adjustment
     * @return The adjusted position by moving it based on the difference between <em>query1</em> and
     * <em>query2</em>
     * @see #reposition(CharSequence, int[], CharSequence)
     */
    public static int repositionCursor(CharSequence query1, int position1, CharSequence query2) {
        int[] positions = { position1, position1 };
        reposition(query1, positions, query2);
        return positions[0];
    }

    /**
     * Re-adjusts the given positions, which is based on the non-escaped version of the given
     * <em>query</em>, by making sure it is pointing at the same position within <em>query</em>,
     * which contains references (escape characters).
     * <p>
     * The escape characters are either \b, \t, \n, \f, \r, \", \' and \0 through \7.
     * <p>
     * <b>Important:</b> The given query should contain the exact same amount of whitespace than the
     * query used to calculate the given positions.
     *
     * @param query The query that may contain escape characters
     * @param positions The position within the non-escaped version of the given query, which is
     * either a single element position or two positions that is used as a text range. After execution
     * contains the adjusted positions by moving it based on the difference between the escape and
     * non-escaped versions of the query
     * @since 2.5
     */
    public static void repositionJava(CharSequence query, int[] positions) {

        if ((query == null) || (query.length() == 0)) {
            return;
        }

        StringBuilder sb = new StringBuilder(query);

        for (int index = 0, count = sb.length(); index < count; index++) {

            char character = sb.charAt(index);

            if (isJavaEscapedCharacter(character)) {

                // Translate both positions because the special
                // character is written with its escape character
                if (index < positions[0]) {
                    positions[0]++;
                    positions[1]++;
                }
                // Only translate the end position because the start
                // position is before the current index
                else if (index < positions[1]) {
                    positions[1]++;
                }
            }
        }
    }

    /**
     * Determines whether the given string starts with the given prefix and ignores the case. If the
     * prefix is <code>null</code> or an empty string, then <code>true</code> is always returned.
     *
     * @param string The string to check if its beginning matches the prefix
     * @param prefix The prefix used to test matching the beginning of the sequence of characters
     * @return <code>true</code> if the given string begins with the given prefix and ignores the
     * case; <code>false</code> otherwise
     *
     * @since 2.5
     */
    public static boolean startWithIgnoreCase(String string, String prefix) {

        if (stringIsEmpty(prefix)) {
            return true;
        }

        return string.regionMatches(true, 0, prefix, 0, prefix.length());
    }

    /**
     * Determines whether the specified string is <code>null</code>, empty, or contains only
     * whitespace characters.
     *
     * @param text The sequence of character to test if it is <code>null</code> or only contains
     * whitespace
     * @return <code>true</code> if the given string is <code>null</code> or only contains whitespace;
     * <code>false</code> otherwise
     */
    public static boolean stringIsEmpty(CharSequence text) {

        if ((text == null) || (text.length() == 0)) {
            return true;
        }

        for (int i = text.length(); i-- > 0;) {
            if (!Character.isWhitespace(text.charAt(i))) {
                return false;
            }
        }

        return true;
    }

    /**
     * Determines whether the specified string is NOT <code>null</code>, NOT empty, or contains at
     * least one non-whitespace character.
     *
     * @param text The sequence of character to test if it is NOT <code>null</code> or does not only
     * contain whitespace
     * @return <code>true</code> if the given string is NOT <code>null</code> or has at least one
     * non-whitespace character; <code>false</code> otherwise
     */
    public static boolean stringIsNotEmpty(CharSequence text) {
        return !stringIsEmpty(text);
    }

    /**
     * Determines whether the two sequence of characters are different, with the appropriate
     * <code>null</code> checks and the case is ignored.
     *
     * @param value1 The first value to check for equality and equivalency
     * @param value2 The second value to check for equality and equivalency
     * @return <code>true</code> if both values are different; <code>false</code> otherwise
     */
    public static boolean stringsAreDifferentIgnoreCase(CharSequence value1, CharSequence value2) {
        return !stringsAreEqualIgnoreCase(value1, value2);
    }

    /**
     * Determines whether the two sequence of characters are equal or equivalent, with the
     * appropriate <code>null</code> checks and the case is ignored.
     *
     * @param value1 The first value to check for equality and equivalency
     * @param value2 The second value to check for equality and equivalency
     * @return <code>true</code> if both values are <code>null</code>, equal or equivalent;
     * <code>false</code> otherwise
     */
    public static boolean stringsAreEqualIgnoreCase(CharSequence value1, CharSequence value2) {

        // Both are equal or both are null
        if ((value1 == value2) || (value1 == null) && (value2 == null)) {
            return true;
        }

        // One is null but the other is not
        if ((value1 == null) || (value2 == null)) {
            return false;
        }

        return value1.toString().equalsIgnoreCase(value2.toString());
    }

    /**
     * Converts the string representation of the escape characters contained by the given {@link
     * CharSequence} into the actual escape characters. For example, the string '\\b' is converted
     * into the character value '\b'.
     *
     * @param value The sequence of characters to convert to an escaped version
     * @param position This is a one element array that needs to be adjusted when an escape
     * character is converted
     * @return The new sequence of characters that contains escape characters rather than their
     * string representation
     */
    public static String unescape(CharSequence value, int[] position) {

        StringBuilder sb = new StringBuilder(value.length());
        int originalPosition = position[0];

        for (int index = 0, count = value.length(); index < count; index++) {

            char character = value.charAt(index);

            if ((character == '\\') && (index + 1 < count)) {
                character = value.charAt(++index);

                switch (character) {
                    // Standard escape character
                    case 'b':  sb.append("\b"); if (index <= originalPosition) position[0]--; break;
                    case 't':  sb.append("\t"); if (index <= originalPosition) position[0]--; break;
                    case 'n':  sb.append("\n"); if (index <= originalPosition) position[0]--; break;
                    case 'f':  sb.append("\f"); if (index <= originalPosition) position[0]--; break;
                    case 'r':  sb.append("\r"); if (index <= originalPosition) position[0]--; break;
                    case '"':  sb.append("\""); if (index <= originalPosition) position[0]--; break;
                    case '\\': sb.append("\\"); if (index <= originalPosition) position[0]--; break;
                    case '0':  sb.append("\0"); if (index <= originalPosition) position[0]--; break;
                    case '1':  sb.append("\1"); if (index <= originalPosition) position[0]--; break;
                    case '2':  sb.append("\2"); if (index <= originalPosition) position[0]--; break;
                    case '3':  sb.append("\3"); if (index <= originalPosition) position[0]--; break;
                    case '4':  sb.append("\4"); if (index <= originalPosition) position[0]--; break;
                    case '5':  sb.append("\5"); if (index <= originalPosition) position[0]--; break;
                    case '6':  sb.append("\6"); if (index <= originalPosition) position[0]--; break;
                    case '7':  sb.append("\7"); if (index <= originalPosition) position[0]--; break;

                    // Unicode
                    case 'u': {
                        // Convert the hexadecimal digit into a char
                        String hexadecimals = value.subSequence(index + 1, index + 5).toString();
                        char unicode = (char) Integer.parseInt(hexadecimals, 16);
                        sb.append(unicode);

                        // Adjust the position and make sure if the position is within the unicode
                        // value, then it's only adjusted to be at the beginning of the unicode value
                        if ((originalPosition > index - 1) && (originalPosition <= index + 5)) {
                            position[0] -= (originalPosition - index + 1);
                        }
                        else if (index <= originalPosition) {
                            position[0] -= 5;
                        }

                        index += 4;
                        break;
                    }
                    // Non-escape character
                    default: {
                        sb.append(character);
                    }
                }
            }
            else {
                sb.append(character);
            }
        }

        return sb.toString();
    }

    /**
     * Returns the string literal without the single or double quotes. Any two consecutive single
     * quotes will be converted into a single quote.
     *
     * @param text The original text to unquote if it has ' at the beginning and the end
     * @return The unquoted text
     */
    public static String unquote(String text) {

        // Nothing to unquote
        if ((text == null) || (text.length() == 0)) {
            return text;
        }

        int startIndex = 0;
        int endIndex = text.length();

        // Skip the leading single quote
        if (isQuote(text.charAt(0))) {
            startIndex = 1;
        }

        // Skip the trailing single quote
        if ((endIndex - 1 >= startIndex) && isQuote(text.charAt(endIndex - 1))) {
            endIndex--;
        }

        text = text.substring(startIndex, endIndex);
        text = text.replace("''", "'");
        return text;
    }

    /**
     * Determines whether the values are different, with the appropriate <code>null</code> checks.
     *
     * @param value1 The first value to check for equality and equivalency
     * @param value2 The second value to check for equality and equivalency
     * @return <code>true</code> if both values are different; <code>true</code> if they are both
     * <code>null</code>, equal or equivalent
     */
    public static boolean valuesAreDifferent(Object value1, Object value2) {
        return !valuesAreEqual(value1, value2);
    }

    /**
     * Determines whether the values are equal or equivalent, with the appropriate <code>null</code>
     * checks.
     *
     * @param value1 The first value to check for equality and equivalency
     * @param value2 The second value to check for equality and equivalency
     * @return <code>true</code> if both values are <code>null</code>, equal or equivalent;
     * <code>false</code> otherwise
     */
    public static boolean valuesAreEqual(Object value1, Object value2) {

        // Both are equal or both are null
        if ((value1 == value2) || (value1 == null) && (value2 == null)) {
            return true;
        }

        // One is null but the other is not
        if ((value1 == null) || (value2 == null)) {
            return false;
        }

        return value1.equals(value2);
    }
}
