/*
 * 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.ignite.springdata22.repository.query;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.jetbrains.annotations.Nullable;
import org.springframework.data.util.Streamable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import static java.util.regex.Pattern.CASE_INSENSITIVE;
import static java.util.regex.Pattern.DOTALL;
import static java.util.regex.Pattern.compile;

/**
 * Simple utility class to create queries.
 *
 * @author Oliver Gierke
 * @author Kevin Raymond
 * @author Thomas Darimont
 * @author Komi Innocent
 * @author Christoph Strobl
 * @author Mark Paluch
 * @author Sébastien Péralta
 * @author Jens Schauder
 * @author Nils Borrmann
 * @author Reda.Housni -Alaoui
 */
public abstract class QueryUtils {
    /**
     * The constant COUNT_QUERY_STRING.
     */
    public static final String COUNT_QUERY_STRING = "select count(%s) from %s x";

    /**
     * The constant DELETE_ALL_QUERY_STRING.
     */
    public static final String DELETE_ALL_QUERY_STRING = "delete from %s x";

    /**
     * Used Regex/Unicode categories (see http://www.unicode.org/reports/tr18/#General_Category_Property): Z Separator
     * Cc Control Cf Format P Punctuation
     */
    private static final String IDENTIFIER = "[._[\\P{Z}&&\\P{Cc}&&\\P{Cf}&&\\P{P}]]+";

    /**
     * The Colon no double colon.
     */
    static final String COLON_NO_DOUBLE_COLON = "(?<![:\\\\]):";

    /**
     * The Identifier group.
     */
    static final String IDENTIFIER_GROUP = String.format("(%s)", IDENTIFIER);

    /** */
    private static final String COUNT_REPLACEMENT_TEMPLATE = "select count(%s) $5$6$7";

    /** */
    private static final String SIMPLE_COUNT_VALUE = "$2";

    /** */
    private static final String COMPLEX_COUNT_VALUE = "$3$6";

    /** */
    private static final String ORDER_BY_PART = "(?iu)\\s+order\\s+by\\s+.*$";

    /** */
    private static final Pattern ALIAS_MATCH;

    /** */
    private static final Pattern COUNT_MATCH;

    /** */
    private static final Pattern PROJECTION_CLAUSE = Pattern
        .compile("select\\s+(.+)\\s+from", Pattern.CASE_INSENSITIVE);

    /** */
    private static final String JOIN = "join\\s+(fetch\\s+)?" + IDENTIFIER + "\\s+(as\\s+)?" + IDENTIFIER_GROUP;

    /** */
    private static final Pattern JOIN_PATTERN = Pattern.compile(JOIN, Pattern.CASE_INSENSITIVE);

    /** */
    private static final String EQUALS_CONDITION_STRING = "%s.%s = :%s";

    /** */
    private static final Pattern NAMED_PARAMETER = Pattern.compile(
        COLON_NO_DOUBLE_COLON + IDENTIFIER + "|\\#" + IDENTIFIER, CASE_INSENSITIVE);

    /** */
    private static final Pattern CONSTRUCTOR_EXPRESSION;

    /** */
    private static final int QUERY_JOIN_ALIAS_GROUP_INDEX = 3;

    /** */
    private static final int VARIABLE_NAME_GROUP_INDEX = 4;

    /** */
    private static final Pattern FUNCTION_PATTERN;

    static {
        StringBuilder builder = new StringBuilder();
        builder.append("(?<=from)"); // from as starting delimiter
        builder.append("(?:\\s)+"); // at least one space separating
        builder.append(IDENTIFIER_GROUP); // Entity name, can be qualified (any
        builder.append("(?:\\sas)*"); // exclude possible "as" keyword
        builder.append("(?:\\s)+"); // at least one space separating
        builder.append("(?!(?:where))(\\w+)"); // the actual alias

        ALIAS_MATCH = compile(builder.toString(), CASE_INSENSITIVE);

        builder = new StringBuilder();
        builder.append("(select\\s+((distinct )?(.+?)?)\\s+)?(from\\s+");
        builder.append(IDENTIFIER);
        builder.append("(?:\\s+as)?\\s+)");
        builder.append(IDENTIFIER_GROUP);
        builder.append("(.*)");

        COUNT_MATCH = compile(builder.toString(), CASE_INSENSITIVE);

        builder = new StringBuilder();
        builder.append("select");
        builder.append("\\s+"); // at least one space separating
        builder.append("(.*\\s+)?"); // anything in between (e.g. distinct) at least one space separating
        builder.append("new");
        builder.append("\\s+"); // at least one space separating
        builder.append(IDENTIFIER);
        builder.append("\\s*"); // zero to unlimited space separating
        builder.append("\\(");
        builder.append(".*");
        builder.append("\\)");

        CONSTRUCTOR_EXPRESSION = compile(builder.toString(), CASE_INSENSITIVE + DOTALL);

        builder = new StringBuilder();
        // any function call including parameters within the brackets
        builder.append("\\w+\\s*\\([\\w\\.,\\s'=]+\\)");
        // the potential alias
        builder.append("\\s+[as|AS]+\\s+(([\\w\\.]+))");

        FUNCTION_PATTERN = compile(builder.toString());
    }

    /**
     * Private constructor to prevent instantiation.
     */
    private QueryUtils() {
        // No-op.
    }

    /**
     * Returns the query string to execute an exists query for the given id attributes.
     *
     * @param entityName        the name of the entity to create the query for, must not be {@literal null}.
     * @param cntQryPlaceHolder the placeholder for the count clause, must not be {@literal null}.
     * @param idAttrs           the id attributes for the entity, must not be {@literal null}.
     * @return the exists query string
     */
    public static String getExistsQueryString(String entityName,
        String cntQryPlaceHolder,
        Iterable<String> idAttrs) {
        String whereClause = Streamable.of(idAttrs).stream() //
            .map(idAttribute -> String.format(EQUALS_CONDITION_STRING, "x", idAttribute,
                idAttribute)) //
            .collect(Collectors.joining(" AND ", " WHERE ", ""));

        return String.format(COUNT_QUERY_STRING, cntQryPlaceHolder, entityName) + whereClause;
    }

    /**
     * Returns the query string for the given class name.
     *
     * @param template   must not be {@literal null}.
     * @param entityName must not be {@literal null}.
     * @return the template with placeholders replaced by the {@literal entityName}. Guaranteed to be not {@literal
     *     null}.
     */
    public static String getQueryString(String template, String entityName) {
        Assert.hasText(entityName, "Entity name must not be null or empty!");

        return String.format(template, entityName);
    }

    /**
     * Returns the aliases used for {@code left (outer) join}s.
     *
     * @param qry a query string to extract the aliases of joins from. Must not be {@literal null}.
     * @return a {@literal Set} of aliases used in the query. Guaranteed to be not {@literal null}.
     */
    static Set<String> getOuterJoinAliases(String qry) {
        Set<String> result = new HashSet<>();
        Matcher matcher = JOIN_PATTERN.matcher(qry);

        while (matcher.find()) {
            String alias = matcher.group(QUERY_JOIN_ALIAS_GROUP_INDEX);
            if (StringUtils.hasText(alias))
                result.add(alias);
        }

        return result;
    }

    /**
     * Returns the aliases used for aggregate functions like {@code SUM, COUNT, ...}.
     *
     * @param qry a {@literal String} containing a query. Must not be {@literal null}.
     * @return a {@literal Set} containing all found aliases. Guaranteed to be not {@literal null}.
     */
    static Set<String> getFunctionAliases(String qry) {
        Set<String> result = new HashSet<>();
        Matcher matcher = FUNCTION_PATTERN.matcher(qry);

        while (matcher.find()) {
            String alias = matcher.group(1);

            if (StringUtils.hasText(alias))
                result.add(alias);
        }

        return result;
    }

    /**
     * Resolves the alias for the entity to be retrieved from the given JPA query.
     *
     * @param qry must not be {@literal null}.
     * @return Might return {@literal null}.
     */
    @Nullable
    static String detectAlias(String qry) {
        Matcher matcher = ALIAS_MATCH.matcher(qry);

        return matcher.find() ? matcher.group(2) : null;
    }

    /**
     * Creates a count projected query from the given original query.
     *
     * @param originalQry   must not be {@literal null}.
     * @param cntProjection may be {@literal null}.
     * @return a query String to be used a count query for pagination. Guaranteed to be not {@literal null}.
     */
    static String createCountQueryFor(String originalQry, @Nullable String cntProjection) {
        Assert.hasText(originalQry, "OriginalQuery must not be null or empty!");

        Matcher matcher = COUNT_MATCH.matcher(originalQry);
        String countQuery;

        if (cntProjection == null) {
            String variable = matcher.matches() ? matcher.group(VARIABLE_NAME_GROUP_INDEX) : null;
            boolean useVariable = variable != null && StringUtils.hasText(variable) && !variable.startsWith("new")
                && !variable.startsWith("count(") && !variable.contains(",");

            String replacement = useVariable ? SIMPLE_COUNT_VALUE : COMPLEX_COUNT_VALUE;
            countQuery = matcher.replaceFirst(String.format(COUNT_REPLACEMENT_TEMPLATE, replacement));
        }
        else
            countQuery = matcher.replaceFirst(String.format(COUNT_REPLACEMENT_TEMPLATE, cntProjection));

        return countQuery.replaceFirst(ORDER_BY_PART, "");
    }

    /**
     * Returns whether the given JPQL query contains a constructor expression.
     *
     * @param qry must not be {@literal null} or empty.
     * @return boolean
     */
    public static boolean hasConstructorExpression(String qry) {
        Assert.hasText(qry, "Query must not be null or empty!");

        return CONSTRUCTOR_EXPRESSION.matcher(qry).find();
    }

    /**
     * Returns the projection part of the query, i.e. everything between {@code select} and {@code from}.
     *
     * @param qry must not be {@literal null} or empty.
     * @return projection
     */
    public static String getProjection(String qry) {
        Assert.hasText(qry, "Query must not be null or empty!");

        Matcher matcher = PROJECTION_CLAUSE.matcher(qry);
        String projection = matcher.find() ? matcher.group(1) : "";
        return projection.trim();
    }
}
