/*
 * 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 org.apache.ignite.internal.util.typedef.internal.S;

/**
 * Ignite query helper class. For internal use only.
 *
 * @author Apache Ignite Team
 * @author Manuel Núñez (manuel.nunez@hawkore.com)
 */
public class IgniteQuery {
    /** */
    enum Option {
        /** Query will be used with Sort object. */
        SORTING,

        /** Query will be used with Pageable object. */
        PAGINATION,

        /** No advanced option. */
        NONE
    }

    /**
     * Query text string.
     */
    private final String qrySql;

    /**
     * Whether this is a SQL fields query
     */
    private final boolean isFieldQuery;

    /**
     * Whether this is Text query
     */
    private final boolean isTextQuery;

    /**
     * Whether was autogenerated (by method name)
     */
    private final boolean isAutogenerated;

    /**
     * Type of option.
     */
    private final Option option;

    /**
     * @param qrySql          the query string.
     * @param isFieldQuery    Is field query.
     * @param isTextQuery     Is a TextQuery
     * @param isAutogenerated query was autogenerated
     * @param option          Option.
     */
    public IgniteQuery(String qrySql,
        boolean isFieldQuery,
        boolean isTextQuery,
        boolean isAutogenerated,
        Option option) {
        this.qrySql = qrySql;
        this.isFieldQuery = isFieldQuery;
        this.isTextQuery = isTextQuery;
        this.isAutogenerated = isAutogenerated;
        this.option = option;
    }

    /**
     * Text string of the query.
     *
     * @return SQL query text string.
     */
    public String qryStr() {
        return qrySql;
    }

    /**
     * Returns {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
     *
     * @return {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
     */
    public boolean isFieldQuery() {
        return isFieldQuery;
    }

    /**
     * Returns {@code true} if it's Ignite Text query, {@code false} otherwise.
     *
     * @return {@code true} if it's Ignite Text query, {@code false} otherwise.
     */
    public boolean isTextQuery() {
        return isTextQuery;
    }

    /**
     * Returns {@code true} if it's autogenerated, {@code false} otherwise.
     *
     * @return {@code true} if it's autogenerated, {@code false} otherwise.
     */
    public boolean isAutogenerated() {
        return isAutogenerated;
    }

    /**
     * Advanced querying option.
     *
     * @return querying option.
     */
    public Option options() {
        return option;
    }

    /** */
    @Override public String toString() {
        return S.toString(IgniteQuery.class, this);
    }
}
