/*
 * Copyright (c) 2011, 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.tools.model.query;

import java.io.IOException;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.Assert;
import org.eclipse.persistence.jpa.jpql.parser.JPQLExpression;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.tools.model.IJPQLQueryBuilder;
import org.eclipse.persistence.jpa.jpql.tools.spi.IManagedTypeProvider;

/**
 * This is the root of the {@link StateObject} hierarchy that represents a JPQL query. The only
 * child of this state object is one of the three possible query statements.
 *
 * @see DeleteStatementStateObject
 * @see SelectStatementStateObject
 * @see UpdateStatementStateObject
 * @see org.eclipse.persistence.jpa.jpql.parser.JPQLExpression JPQLExpression
 *
 * @version 2.4
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public class JPQLQueryStateObject extends AbstractStateObject {

    /**
     * The external form of a provider that gives access to the JPA metadata.
     */
    private IManagedTypeProvider provider;

    /**
     * The builder that can create any {@link StateObject} for any given JPQL fragment.
     */
    private IJPQLQueryBuilder queryBuilder;

    /**
     * One of the possible three statements.
     */
    private StateObject queryStatement;

    /**
     * Notifies the query statement has changed.
     */
    public static final String QUERY_STATEMENT_PROPERTY = "statement";

    /**
     * Creates a new <code>JPQLQueryStateObject</code>.
     *
     * @param queryBuilder The builder that can create any {@link StateObject} for any given JPQL
     * fragment when using a parse method
     * @param provider The external form of a provider that gives access to the JPA metadata
     * @exception NullPointerException If one of the given arguments is <code>null</code>
     */
    public JPQLQueryStateObject(IJPQLQueryBuilder queryBuilder, IManagedTypeProvider provider) {
        super(null);
        initialize(queryBuilder, provider);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void accept(StateObjectVisitor visitor) {
        visitor.visit(this);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void addChildren(List<StateObject> children) {
        super.addChildren(children);
        if (queryStatement != null) {
            children.add(queryStatement);
        }
    }

    /**
     * Changes the query statement to be a <code><b>DELETE</b></code> statement.
     *
     * @return The new root object of the <code><b>DELETE</b></code> statement
     */
    public DeleteStatementStateObject addDeleteStatement() {
        DeleteStatementStateObject stateObject = new DeleteStatementStateObject(this);
        setQueryStatement(stateObject);
        return stateObject;
    }

    /**
     * Changes the query statement to be a <code><b>SELECT</b></code> statement. The <code><b>SELECT</b></code>
     * clause will have the <code><b>DISTINCT</b></code> identifier set.
     *
     * @return The new root object of the <code><b>SELECT</b></code> statement
     */
    public SelectStatementStateObject addDistinctSelectStatement() {
        SelectStatementStateObject stateObject = new SelectStatementStateObject(this);
        stateObject.getSelectClause().toggleDistinct();
        setQueryStatement(stateObject);
        return stateObject;
    }

    /**
     * Changes the query statement to be a <code><b>SELECT</b></code> statement.
     *
     * @return The new root object of the <code><b>SELECT</b></code> statement
     */
    public SelectStatementStateObject addSelectStatement() {
        SelectStatementStateObject stateObject = new SelectStatementStateObject(this);
        setQueryStatement(stateObject);
        return stateObject;
    }

    /**
     * Changes the query statement to be a <code><b>SELECT</b></code> statement.
     *
     * @param jpqlFragment The portion of the query representing the select items, excluding the
     * <code><b>SELECT</b></code> identifier
     * @return The new root object of the <code><b>SELECT</b></code> statement
     */
    public SelectStatementStateObject addSelectStatement(String jpqlFragment) {
        SelectStatementStateObject stateObject = new SelectStatementStateObject(this);
        stateObject.getSelectClause().parse(jpqlFragment);
        setQueryStatement(stateObject);
        return stateObject;
    }

    /**
     * Changes the query statement to be a <code><b>UPDATE</b></code> statement.
     *
     * @return The new root object of the <code><b>UPDTE</b></code> statement
     */
    public UpdateStatementStateObject addUpdateStatement() {
        UpdateStatementStateObject stateObject = new UpdateStatementStateObject(this);
        setQueryStatement(stateObject);
        return stateObject;
    }

    /**
     * Changes the query statement to be a <code><b>UPDATE</b></code> statement.
     *
     * @param jpqlFragment The portion of the query representing the select items, excluding the
     * <code><b>UPDATE</b></code> identifier
     * @return The new root object of the <code><b>UPDATE</b></code> statement
     */
    public UpdateStatementStateObject addUpdateStatement(String jpqlFragment) {
        UpdateStatementStateObject stateObject = new UpdateStatementStateObject(this);
        stateObject.getModifyClause().parse(jpqlFragment);
        setQueryStatement(stateObject);
        return stateObject;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected StateObject checkParent(StateObject parent) {
        return parent;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public DeclarationStateObject getDeclaration() {
        return (queryStatement == null) ? null : queryStatement.getDeclaration();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public JPQLExpression getExpression() {
        return (JPQLExpression) super.getExpression();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public JPQLGrammar getGrammar() {
        return queryBuilder.getGrammar();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IManagedTypeProvider getManagedTypeProvider() {
        return provider;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public StateObject getParent() {
        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IJPQLQueryBuilder getQueryBuilder() {
        return queryBuilder;
    }

    /**
     * Returns the only child of this state object, which represents one of the three query statement.
     *
     * @return The state object representing the query statement, which was created based on the
     * query type
     */
    public StateObject getQueryStatement() {
        return queryStatement;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public JPQLQueryStateObject getRoot() {
        return this;
    }

    /**
     * Determines whether a query statement has been defined.
     *
     * @return <code>true</code> if there is a query statement defined; <code>false</code> otherwise
     */
    public boolean hasQueryStatement() {
        return queryStatement != null;
    }

    /**
     * Initializes this <code>JPQLQueryStateObject</code>.
     *
     * @param queryBuilder The builder that can create any {@link StateObject} for any given JPQL fragment
     * @param provider The external form that gives access to the JPA metadata
     * @exception NullPointerException If one of the given arguments is <code>null</code>
     */
    protected void initialize(IJPQLQueryBuilder queryBuilder, IManagedTypeProvider provider) {

        Assert.isNotNull(queryBuilder, "IJPQLQueryBuilder cannot be null");
        Assert.isNotNull(provider,     "IManagedTypeProvider cannot be null");

        this.provider     = provider;
        this.queryBuilder = queryBuilder;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isEquivalent(StateObject stateObject) {

        if (super.isEquivalent(stateObject)) {
            JPQLQueryStateObject jpqlStateObject = (JPQLQueryStateObject) stateObject;
            return areEquivalent(queryStatement, jpqlStateObject.queryStatement);
        }

        return false;
    }

    /**
     * Parses the given JPQL fragment as this state object's query statement.
     *
     * @param jpqlFragment The portion of the query to parse
     * @param queryBNFId The unique identifier of the BNF that determines how to parse the fragment
     */
    public void parse(CharSequence jpqlFragment, String queryBNFId) {
        StateObject stateObject = buildStateObject(jpqlFragment, queryBNFId);
        setQueryStatement(stateObject);
    }

    /**
     * Keeps a reference of the {@link JPQLExpression parsed object} object, which should only be
     * done when this object is instantiated during the conversion of a parsed JPQL query into
     * {@link StateObject StateObjects}.
     *
     * @param expression The {@link JPQLExpression parsed object} representing the JPQL query
     */
    public void setExpression(JPQLExpression expression) {
        super.setExpression(expression);
    }

    /**
     * Sets the only child of this state object, which represents one of the three query statement.
     *
     * @param queryStatement The state object representing the query statement, which was created
     * based on the query type
     */
    public void setQueryStatement(StateObject queryStatement) {
        StateObject oldStatement = this.queryStatement;
        this.queryStatement = parent(queryStatement);
        firePropertyChanged(QUERY_STATEMENT_PROPERTY, oldStatement, queryStatement);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void toTextInternal(Appendable writer) throws IOException {
        if (queryStatement != null) {
            queryStatement.toString(writer);
        }
    }
}
