/*
 * Copyright (c) 2006, 2021 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.tools;

import org.eclipse.persistence.jpa.jpql.parser.IdentifierRole;
import org.eclipse.persistence.jpa.jpql.tools.spi.IEntity;
import org.eclipse.persistence.jpa.jpql.tools.spi.IMapping;
import org.eclipse.persistence.jpa.jpql.tools.spi.IType;

/**
 * This object stores the various proposals available for content assist for a certain position
 * within a JPQL query. The proposals are stored in categories (abstract schema types, identifiers,
 * identification variables and mappings).
 * <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.5
 * @since 2.3
 * @author Pascal Filion
 */
public interface ContentAssistProposals {

    /**
     * Returns the collection of possible abstract schema types.
     *
     * @return The {@link IEntity entities} defined in the persistence context
     */
    Iterable<IEntity> abstractSchemaTypes();

    /**
     * Creates a new JPQL query by inserting the given proposal at the given position. The updated
     * JPQL query and position will be adjusted by converting some characters into their corresponding
     * escaped characters, for instance '\r' will be converted to '\\r.
     * <p>
     * The replacement will also handle compound JPQL identifiers when updating the JPQL query.
     * <p>
     * Example: If the cursor is within "IS NOT N|" and the proposal is "IS NOT NULL", then "IS NOT"
     * will not be added twice. If the word to replace is "IS NULL" and the proposal is "IS NOT NULL",
     * then "NOT" will be inserted between "IS" and "NULL".
     *
     * @param jpqlQuery The JPQL query to modify with the given proposal
     * @param proposal The proposal to insert into the query
     * @param position The position of insertion
     * @param insert Flag that determines if the partial word following the cursor should be left
     * intact or should be replaced by the proposal
     * @return The result of inserting the proposal into the query, including the adjust position, if
     * it was required
     */
    ResultQuery buildEscapedQuery(String jpqlQuery, String proposal, int position, boolean insert);

    /**
     * Creates a new JPQL query by inserting the given proposal at the given position.
     * <p>
     * The replacement will also handle compound JPQL identifiers when updating the JPQL query.
     * <p>
     * Example: If the cursor is within "IS NOT N|" and the proposal is "IS NOT NULL", then "IS NOT"
     * will not be added twice. If the word to replace is "IS NULL" and the proposal is "IS NOT NULL",
     * then "NOT" will be inserted between "IS" and "NULL".
     *
     * @param jpqlQuery The JPQL query to modify with the given proposal
     * @param proposal The proposal to insert into the query
     * @param position The position of insertion
     * @param insert Flag that determines if the partial word following the cursor should be left
     * intact or should be replaced by the proposal
     * @return The result of inserting the proposal into the query, including the adjust position, if
     * it was required
     */
    ResultQuery buildQuery(String jpqlQuery, String proposal, int position, boolean insert);

    /**
     * Creates a new JPQL query by inserting the given proposal at the given position. The updated
     * JPQL query and position will be adjusted by converting some characters into their corresponding
     * escaped characters, for instance '&gt;' will be converted to '&amp;gt;'.
     * <p>
     * The replacement will also handle compound JPQL identifiers when updating the JPQL query.
     * <p>
     * Example: If the cursor is within "IS NOT N|" and the proposal is "IS NOT NULL", then "IS NOT"
     * will not be added twice. If the word to replace is "IS NULL" and the proposal is "IS NOT NULL",
     * then "NOT" will be inserted between "IS" and "NULL".
     *
     * @param jpqlQuery The JPQL query to modify with the given proposal, which should be the non-
     * converted string, i.e. any escaped characters should not be converted
     * @param proposal The proposal to insert into the query
     * @param position The position of insertion, which was derived from the parsed tree representation
     * of the JPQL query
     * @param insert Flag that determines if the partial word following the cursor should be left
     * intact or should be replaced by the proposal
     * @return The result of inserting the proposal into the query, including the adjust position, if
     * it was required
     * @since 2.5
     */
    ResultQuery buildXmlQuery(String jpqlQuery, String proposal, int position, boolean insert);

    /**
     * Returns the filtered list of possible class names. This is usually available when the cursor
     * is within the constructor name of the constructor expression.
     *
     * @return The filtered list of possible class names
     * @see org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression
     * @since 2.5
     */
    Iterable<String> classNames();

    /**
     * Returns the filtered list of possible column names.
     *
     * @return The filtered list of possible column names
     * @since 2.5
     */
    Iterable<String> columnNames();

    /**
     * Returns the filtered list of possible enum constant names. This is usually available when the
     * cursor is after the dot separating a fully qualified enum type and the enum constant.
     *
     * @return The filtered list of possible enum constant names associated with its enum type
     * @since 2.5
     */
    Iterable<EnumProposals> enumConstant();

    /**
     * Retrieves the abstract schema type that is mapped with the given identification variable.
     *
     * @param identificationVariable The identification variable that, if defined as a range variable,
     * will be mapped to a managed type
     * @return The abstract schema type mapped with the given identification variable or
     * <code>null</code> if the given variable is mapped to something else or not mapped to anything
     */
    IEntity getAbstractSchemaType(String identificationVariable);

    /**
     * @since 2.5
     */
    ClassType getClassType();

    /**
     * Returns the role of the given JPQL identifier.
     *
     * @param identifier The JPQL identifier to retrieve its role
     * @return The {@link IdentifierRole} for the given JPQL identifier or <code>null</code> if no
     * role was defined or if the given string is not a valid JPQL identifier
     * @since 2.4
     */
    IdentifierRole getIdentifierRole(String identifier);

    /**
     * Determines whether there is at least one proposals.
     *
     * @return <code>true</code> if there is at least one proposal; otherwise <code>false</code>
     */
    boolean hasProposals();

    /**
     * Returns the collection of possible identification variables.
     *
     * @return The list of possible identification variables
     */
    Iterable<String> identificationVariables();

    /**
     * Returns the collection of possible JPQL identifiers.
     *
     * @return The list of possible JPQL identifiers
     */
    Iterable<String> identifiers();

    /**
     * Returns the collection of possible {@link IMapping mappings}, which can be state fields,
     * association fields and/or collection fields depending on the location used to retrieve the
     * possible proposals.
     *
     * @return The list of possible proposals {@link IMapping mappings}
     */
    Iterable<IMapping> mappings();

    /**
     * Returns the filtered list of possible table names.
     *
     * @return The filtered list of possible table names
     * @since 2.5
     */
    Iterable<String> tableNames();

    /**
     * This enumeration determines the type of classes returned by {@link ContentAssistProposals#classNames()}.
     */
    enum ClassType {

        /**
         * Indicates the only class type allowed is an enum type.
         */
        ENUM,

        /**
         * Indicates the class has to be instantiable, i.e. anonymous, interfaces, enums, annotations
         * are not allowed.
         */
        INSTANTIABLE
    }

    /**
     * Holds onto the {@link IType} of the enum type and the list of possible enum constants.
     *
     * @version 2.5
     */
    interface EnumProposals {

        /**
         * Returns the list of enum constants that have been filtered.
         */
        Iterable<String> enumConstants();

        /**
         * The {@link IType} representing the enum type.
         *
         * @return The {@link IType} representing the enum type
         */
        IType enumType();
    }
}
