/*
 * Copyright (c) 2012, 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.tests.jpql.tools;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.JPQLQueryDeclaration.Type;
import org.eclipse.persistence.jpa.jpql.parser.AbstractTraverseChildrenVisitor;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.tools.JPQLQueryContext;
import org.eclipse.persistence.jpa.jpql.tools.resolver.Declaration;
import org.eclipse.persistence.jpa.jpql.tools.spi.IQuery;
import org.eclipse.persistence.jpa.jpql.utility.CollectionTools;
import org.eclipse.persistence.jpa.tests.jpql.JPQLCoreTest;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLGrammarTestHelper;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.DeleteClauseTester;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.ExpressionTester;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.JoinTester;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.RangeVariableDeclarationTester;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.UpdateClauseTester;
import org.eclipse.persistence.jpa.tests.jpql.tools.spi.java.JavaQuery;
import org.junit.Test;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.*;
import static org.junit.Assert.*;

/**
 * Unit-tests for {@link Declaration}.
 *
 * @version 2.5
 * @since 2.5
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public abstract class DeclarationTest extends JPQLCoreTest {

    @JPQLGrammarTestHelper
    protected JPQLGrammar jpqlGrammar;
    private JavaQuery virtualQuery;

    protected final IQuery buildQuery(String jpqlQuery) {
        virtualQuery.setExpression(jpqlQuery);
        return virtualQuery;
    }

    protected abstract JPQLQueryContext buildQueryContext();

    protected final CollectionDeclarationTester collectionDeclaration(String collectionPath,
                                                                      String variableName) {

        CollectionDeclarationTester declaration = new CollectionDeclarationTester();
        declaration.baseExpression = collectionPath(collectionPath);
        declaration.rootPath       = collectionPath;

        if (variableName == null) {
            declaration.declarationExpression = fromIn(declaration.baseExpression, nullExpression());
            declaration.variableName          = ExpressionTools.EMPTY_STRING;
        }
        else {
            declaration.declarationExpression = fromIn(declaration.baseExpression, variable(variableName));
            declaration.variableName          = variableName.toUpperCase().intern();
        }

        return declaration;
    }

    protected final CollectionDeclarationTester derivedCollectionDeclaration(String collectionPath) {

        CollectionDeclarationTester declaration = new CollectionDeclarationTester();
        declaration.baseExpression        = collectionPath(collectionPath);
        declaration.rootPath              = collectionPath;
        declaration.declarationExpression = subFromIn(declaration.baseExpression);
        declaration.variableName          = ExpressionTools.EMPTY_STRING;

        return declaration;
    }

    protected final DerivedDeclarationTester derivedRangeDeclaration(String derivedPath,
                                                                     String variableName,
                                                                     JoinTester... joins) {

        DerivedDeclarationTester declaration = new DerivedDeclarationTester();

        if (variableName == null) {
            declaration.baseExpression = rangeVariableDeclaration(collectionPath(derivedPath));
            declaration.variableName   = ExpressionTools.EMPTY_STRING;
        }
        else {

            RangeVariableDeclarationTester rangeVariableDeclaration = rangeVariableDeclaration(
                collectionPath(derivedPath),
                variable(variableName)
            );

            if (variableName.length() == 0) {
                rangeVariableDeclaration.hasSpaceAfterAbstractSchemaName = false;
            }

            declaration.baseExpression = rangeVariableDeclaration;
            declaration.variableName   = variableName.toUpperCase().intern();
        }

        declaration.declarationExpression = identificationVariableDeclaration(declaration.baseExpression, joins);
        declaration.rootPath              = derivedPath;
        declaration.joins                 = CollectionTools.list(joins);

        return declaration;
    }

    protected final RangeDeclarationTester rangeDeclaration(String entityName,
                                                            String variableName) {

        return rangeDeclaration(entityName, variableName, null, new JoinTester[0]);
    }

    protected final RangeDeclarationTester rangeDeclaration(String entityName,
                                                            String variableName,
                                                            ExpressionTester declarationExpression) {

        return rangeDeclaration(entityName, variableName, declarationExpression, new JoinTester[0]);
    }

    protected final RangeDeclarationTester rangeDeclaration(String entityName,
                                                            String variableName,
                                                            ExpressionTester declarationExpression,
                                                            JoinTester... joins) {

        RangeDeclarationTester declaration = new RangeDeclarationTester();

        if (variableName == null) {
            declaration.baseExpression = rangeVariableDeclaration(entityName);
            declaration.variableName   = ExpressionTools.EMPTY_STRING;
        }
        else if (variableName == ExpressionTools.EMPTY_STRING) {
            RangeVariableDeclarationTester rangeVariableDeclaration = rangeVariableDeclaration(entityName);
            rangeVariableDeclaration.hasSpaceAfterAbstractSchemaName = true;
            declaration.baseExpression = rangeVariableDeclaration;
            declaration.variableName   = ExpressionTools.EMPTY_STRING;
        }
        else {
            declaration.baseExpression = rangeVariableDeclaration(entityName, variableName);
            declaration.variableName   = variableName.toUpperCase().intern();
        }

        if (declarationExpression != null) {
            declaration.declarationExpression = declarationExpression;
        }
        else {
            declaration.declarationExpression = identificationVariableDeclaration(declaration.baseExpression, joins);
        }

        declaration.rootPath = entityName;

        if (joins.length == 0) {
            declaration.joins = Collections.emptyList();
        }
        else {
            declaration.joins = CollectionTools.list(joins);
        }

        return declaration;
    }

    protected final RangeDeclarationTester rangeDeclarationWithJoins(String entityName,
                                                                     String variableName,
                                                                     JoinTester... joins) {

        return rangeDeclaration(entityName, variableName, null, joins);
    }

    @Override
    protected void setUpClass() throws Exception {
        super.setUpClass();
        virtualQuery = new JavaQuery(getPersistenceUnit(), null);
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
        virtualQuery.setExpression(null);
    }

    @Override
    protected void tearDownClass() throws Exception {
        virtualQuery = null;
        super.tearDownClass();
    }

    private void test_Declaration_01(boolean tolerant) throws Exception {

        String jpqlQuery = "select e from Employee e";

        testDeclarations(
            jpqlQuery,
            tolerant,
            rangeDeclaration("Employee", "e")
        );
    }

    @Test
    public void test_Declaration_01_1() throws Exception {
        test_Declaration_01(false);
    }

    @Test
    public void test_Declaration_01_2() throws Exception {
        test_Declaration_01(true);
    }

    private void test_Declaration_02(boolean tolerant) throws Exception {

        String jpqlQuery = "select e from Employee e, Address a";

        testDeclarations(
            jpqlQuery,
            tolerant,
            rangeDeclaration("Employee", "e"),
            rangeDeclaration("Address", "a")
        );
    }

    @Test
    public void test_Declaration_02_1() throws Exception {
        test_Declaration_02(false);
    }

    @Test
    public void test_Declaration_02_2() throws Exception {
        test_Declaration_02(true);
    }

    private void test_Declaration_03(boolean tolerant) throws Exception {

        String jpqlQuery = "select e from Employee e join e.manager m, Address a";

        testDeclarations(
            jpqlQuery,
            tolerant,
            rangeDeclarationWithJoins("Employee", "e", join("e.manager", "m")),
            rangeDeclaration("Address", "a")
        );
    }

    @Test
    public void test_Declaration_03_1() throws Exception {
        test_Declaration_03(false);
    }

    @Test
    public void test_Declaration_03_2() throws Exception {
        test_Declaration_03(true);
    }

    private void test_Declaration_04(boolean tolerant) throws Exception {

        String jpqlQuery = "select e from Employee e, in(e.phoneNumbers) p";

        testDeclarations(
            jpqlQuery,
            tolerant,
            rangeDeclaration("Employee", "e"),
            collectionDeclaration("e.phoneNumbers", "p")
        );
    }

    @Test
    public void test_Declaration_04_1() throws Exception {
        test_Declaration_04(false);
    }

    @Test
    public void test_Declaration_04_2() throws Exception {
        test_Declaration_04(true);
    }

    @Test
    public void test_Declaration_05() throws Exception {

        String jpqlQuery = "select e from Employee";

        testDeclarations(
            jpqlQuery,
            true,
            rangeDeclaration("Employee", null)
        );
    }

    private void test_Declaration_06(boolean tolerant) throws Exception {

        String jpqlQuery = "select e from Employee e where e.address = (select a from Address a)";

        JPQLQueryContext queryContext = buildQueryContext();
        queryContext.setTolerant(tolerant);
        queryContext.setQuery(buildQuery(jpqlQuery));

        final Map<Expression, DeclarationTester[]> testers = new HashMap<Expression, DeclarationTester[]>();
        testers.put(queryContext.getJPQLExpression(), new DeclarationTester[] { rangeDeclaration("Employee", "e") });

        queryContext.getJPQLExpression().accept(new AbstractTraverseChildrenVisitor() {
            @Override
            public void visit(SimpleSelectStatement expression) {
                testers.put(expression, new DeclarationTester[] { rangeDeclaration("Address", "a") });
            }
        });

        assertFalse(testers.isEmpty());
        testDeclarations(queryContext, testers);
    }

    @Test
    public void test_Declaration_06_1() throws Exception {
        test_Declaration_06(false);
    }

    @Test
    public void test_Declaration_06_2() throws Exception {
        test_Declaration_06(true);
    }

    private void test_Declaration_07(boolean tolerant) throws Exception {

        String jpqlQuery = "select e from Employee e where e.address = (select d from e.dealers d)";

        JPQLQueryContext queryContext = buildQueryContext();
        queryContext.setTolerant(tolerant);
        queryContext.setQuery(buildQuery(jpqlQuery));

        final Map<Expression, DeclarationTester[]> testers = new HashMap<Expression, DeclarationTester[]>();
        testers.put(queryContext.getJPQLExpression(), new DeclarationTester[] { rangeDeclaration("Employee", "e") });

        queryContext.getJPQLExpression().accept(new AbstractTraverseChildrenVisitor() {
            @Override
            public void visit(SimpleSelectStatement expression) {
                testers.put(expression, new DeclarationTester[] { derivedRangeDeclaration("e.dealers", "d") });
            }
        });

        assertEquals(2, testers.size());
        testDeclarations(queryContext, testers);
    }

    @Test
    public void test_Declaration_07_1() throws Exception {
        test_Declaration_07(false);
    }

    @Test
    public void test_Declaration_07_2() throws Exception {
        test_Declaration_07(true);
    }

    private void test_Declaration_08(boolean tolerant) throws Exception {

        String jpqlQuery = "select e from Employee e where e.address = (select d from Buyer b, IN e.dealers)";

        JPQLQueryContext queryContext = buildQueryContext();
        queryContext.setTolerant(tolerant);
        queryContext.setQuery(buildQuery(jpqlQuery));

        final Map<Expression, DeclarationTester[]> testers = new HashMap<Expression, DeclarationTester[]>();
        testers.put(queryContext.getJPQLExpression(), new DeclarationTester[] { rangeDeclaration("Employee", "e") });

        queryContext.getJPQLExpression().accept(new AbstractTraverseChildrenVisitor() {
            @Override
            public void visit(SimpleSelectStatement expression) {
                testers.put(expression, new DeclarationTester[] {
                    rangeDeclaration("Buyer", "b"),
                    derivedCollectionDeclaration("e.dealers"),
                });
            }
        });

        assertEquals(2, testers.size());
        testDeclarations(queryContext, testers);
    }

    @Test
    public void test_Declaration_08_1() throws Exception {
        test_Declaration_08(false);
    }

    @Test
    public void test_Declaration_08_2() throws Exception {
        test_Declaration_08(true);
    }

    private void test_Declaration_09(final boolean tolerant) throws Exception {

        String jpqlQuery = "select e from Employee e where e.address = (select d from e.dealers)";

        JPQLQueryContext queryContext = buildQueryContext();
        queryContext.setTolerant(tolerant);
        queryContext.setQuery(buildQuery(jpqlQuery));

        final Map<Expression, DeclarationTester[]> testers = new HashMap<Expression, DeclarationTester[]>();
        testers.put(queryContext.getJPQLExpression(), new DeclarationTester[] { rangeDeclaration("Employee", "e") });

        queryContext.getJPQLExpression().accept(new AbstractTraverseChildrenVisitor() {
            @Override
            public void visit(SimpleSelectStatement expression) {
                testers.put(expression, new DeclarationTester[] {
                    derivedRangeDeclaration("e.dealers", tolerant ? null : ExpressionTools.EMPTY_STRING)
                });
            }
        });

        assertEquals(2, testers.size());
        testDeclarations(queryContext, testers);
    }

    @Test
    public void test_Declaration_09_1() throws Exception {
        test_Declaration_09(false);
    }

    @Test
    public void test_Declaration_09_2() throws Exception {
        test_Declaration_09(true);
    }

    private void test_Declaration_10(boolean tolerant) throws Exception {
        String jpqlQuery = "select e from";
        testDeclarations(jpqlQuery, tolerant);
    }

    @Test
    public void test_Declaration_10_1() throws Exception {
        test_Declaration_10(false);
    }

    @Test
    public void test_Declaration_10_2() throws Exception {
        test_Declaration_10(true);
    }

    @Test
    public void test_Declaration_11() throws Exception {

        String jpqlQuery = "select e from Employee e, where e.name = 'JPQL'";

        testDeclarations(
            jpqlQuery,
            true,
            rangeDeclaration("Employee", "e")
        );
    }

    @Test
    public void test_Declaration_12() throws Exception {

        String jpqlQuery = "select e from Employee e, a where e.name = 'JPQL'";

        testDeclarations(
            jpqlQuery,
            true,
            rangeDeclaration("Employee", "e"),
            rangeDeclaration("a", ExpressionTools.EMPTY_STRING)
        );
    }

    private void test_Declaration_13(boolean tolerant) throws Exception {

        String jpqlQuery = "update Employee e set e.name = 'JPQL'";

        UpdateClauseTester updateClause = update(
            "Employee",
            "e",
            set("e.name", string("'JPQL'"))
        );

        testDeclarations(
            jpqlQuery,
            tolerant,
            rangeDeclaration("Employee", "e", updateClause)
        );
    }

    @Test
    public void test_Declaration_13_1() throws Exception {
        test_Declaration_13(false);
    }

    @Test
    public void test_Declaration_13_2() throws Exception {
        test_Declaration_13(true);
    }

    @Test
    public void test_Declaration_14() throws Exception {

        String jpqlQuery = "update set e.name = 'JPQL'";

        UpdateClauseTester updateClause = update(
            nullExpression(),
            set("e.name", string("'JPQL'"))
        );

        testDeclarations(
            jpqlQuery,
            true,
            unknownDeclaration(updateClause)
        );
    }

    @Test
    public void test_Declaration_15() throws Exception {

        String jpqlQuery = "delete from where e.name = 'JPQL'";
        DeleteClauseTester deleteClause = delete(nullExpression());

        testDeclarations(
            jpqlQuery,
            true,
            unknownDeclaration(deleteClause)
        );
    }

    protected final void testDeclarations(JPQLQueryContext queryContext,
                                          Map<Expression, DeclarationTester[]> declarationTesters) {

        for (Map.Entry<Expression, DeclarationTester[]> entry : declarationTesters.entrySet()) {

            Expression expression = entry.getKey();
            DeclarationTester[] testers = entry.getValue();

            if (expression.getRoot() != expression) {
                queryContext.newSubqueryContext(expression);
            }

            // Retrieve the list of Declarations
            List<Declaration> declarations = queryContext.getDeclarations();
            assertNotNull(declarations);
            assertEquals(testers.length, declarations.size());

            // Test each one of them
            for (int index = testers.length; --index >= 0; ) {
                Declaration declaration = declarations.get(index);
                DeclarationTester tester = testers[index];
                tester.test(declaration);
            }

            if (expression.getRoot() != expression) {
                queryContext.disposeSubqueryContext();
            }
        }
    }

    protected final void testDeclarations(String jpqlQuery,
                                          boolean tolerant,
                                          DeclarationTester... declarationTesters) {

        // Build the JPQLQueryContext, which will parse the JPQL query and create the list of Declarations
        JPQLQueryContext queryContext = buildQueryContext();
        queryContext.setTolerant(tolerant);
        queryContext.setQuery(buildQuery(jpqlQuery));

        // Retrieve the list of Declarations
        List<Declaration> declarations = queryContext.getDeclarations();
        assertNotNull(declarations);
        assertEquals(declarationTesters.length, declarations.size());

        // Test each one of them
        for (int index = declarationTesters.length; --index >= 0; ) {
            Declaration declaration = declarations.get(index);
            DeclarationTester tester = declarationTesters[index];
            tester.test(declaration);
        }
    }

    protected final UnknownDeclarationTester unknownDeclaration(ExpressionTester declarationExpression) {

        UnknownDeclarationTester declaration = new UnknownDeclarationTester();
        declaration.baseExpression         = nullExpression();
        declaration.declarationExpression  = declarationExpression;
        declaration.rootPath               = ExpressionTools.EMPTY_STRING;
        declaration.variableName           = ExpressionTools.EMPTY_STRING;

        return declaration;
    }

    protected static abstract class AbstractRangeDeclarationTester extends DeclarationTester {

        protected List<JoinTester> joins;

        @Override
        protected void test(Declaration declaration) {
            super.test(declaration);

            List<Join> declarationJoins = declaration.getJoins();
            assertEquals(!joins.isEmpty(), declaration.hasJoins());
            assertEquals(joins.size(),     declarationJoins.size());

            for (int index = joins.size(); --index >= 0; ) {
                JoinTester expectedJoin = joins.get(index);
                Join resultJoin = declarationJoins.get(index);
                expectedJoin.test(resultJoin);
            }
        }
    }

    protected class CollectionDeclarationTester extends DeclarationTester {
        @Override
        protected Type getType() {
            return Type.COLLECTION;
        }
    }

    protected abstract static class DeclarationTester {

        protected ExpressionTester baseExpression;
        protected ExpressionTester declarationExpression;
        protected String rootPath;
        protected String variableName;

        protected abstract Type getType();

        protected void test(Declaration declaration) {

            baseExpression.test(declaration.getBaseExpression());
            declarationExpression.test(declaration.getDeclarationExpression());

            assertSame  (getType(),    declaration.getType());
            assertSame  (variableName, declaration.getVariableName());
            assertEquals(rootPath,     declaration.getRootPath());
        }
    }

    protected static class DerivedDeclarationTester extends AbstractRangeDeclarationTester {
        @Override
        protected Type getType() {
            return Type.DERIVED;
        }
    }

    protected static class RangeDeclarationTester extends AbstractRangeDeclarationTester {
        @Override
        protected Type getType() {
            return Type.RANGE;
        }
    }

    protected static class UnknownDeclarationTester extends DeclarationTester {
        @Override
        protected Type getType() {
            return Type.UNKNOWN;
        }
    }
}
