/*
 * Copyright (c) 1998, 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 from Oracle TopLink
package org.eclipse.persistence.testing.tests.optimization.queryandsqlcounting;

import java.util.*;

import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.queries.*;

/**
 * Ensure the correct number of SQL statements and queries are generated by queries with joined
 * attributes.
 */
public class JoiningValueholderInstantiationTest extends AutoVerifyTestCase {
    protected QuerySQLTracker tracker = null;
    protected int initialSQLStatements = 0;
    protected int postIndirectionTriggerSQLStatements = 0;
    protected int postSecondQuerySQLStatements = 0;
    protected int initialQueries = 0;
    protected int postIndirectionTriggerQueries = 0;
    protected int postSecondQueryQueries = 0;
    public static final int EXPECTED_INITIAL_STATEMENTS = 1;
    public static final int EXPECTED_INDIRECTION_STATEMENTS = 1;
    public static final int EXPECTED_SECOND_QUERY_STATEMENTS = 2;
    public static final int EXPECTED_INITIAL_QUERIES = 1;
    public static final int EXPECTED_INDIRECTION_QUERIES = 1;
    public static final int EXPECTED_SECOND_QUERY_QUERIES = 2;

    public JoiningValueholderInstantiationTest() {
        setDescription("Ensure the proper SQL statements are generated with joining when valueholders are triggered.");
    }

    @Override
    public void setup() {
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
        tracker = new QuerySQLTracker(getSession());
    }

    @Override
    public void test() {
        ReadAllQuery query = new ReadAllQuery(Employee.class);
        query.addJoinedAttribute("manager");
        Vector emps = (Vector)getSession().executeQuery(query);

        initialSQLStatements = tracker.getSqlStatements().size();
        initialQueries = tracker.getQueries().size();

        Iterator i = emps.iterator();
        while (i.hasNext()) {
            Employee e = (Employee)i.next();
            Employee m = (Employee)e.getManager();
            if (m != null) {
                m.hashCode();
            }
        }

        postIndirectionTriggerSQLStatements = tracker.getSqlStatements().size();
        postIndirectionTriggerQueries = tracker.getQueries().size();

        emps = (Vector)getSession().executeQuery(query);
        i = emps.iterator();
        while (i.hasNext()) {
            Employee e = (Employee)i.next();
            Employee m = (Employee)e.getManager();
            if (m != null) {
                m.hashCode();
            }
        }

        postSecondQuerySQLStatements = tracker.getSqlStatements().size();
        postSecondQueryQueries = tracker.getQueries().size();

    }

    @Override
    public void verify() {
        if (initialSQLStatements != EXPECTED_INITIAL_STATEMENTS) {
            throw new TestErrorException("A ReadAllQuery with joining executed an incorrect number of SQL Statements. " + " expected: " + EXPECTED_INITIAL_STATEMENTS + " got: " + initialSQLStatements);
        }
        if (postIndirectionTriggerSQLStatements != EXPECTED_INDIRECTION_STATEMENTS) {
            throw new TestErrorException("Triggering indirection on a joined attribute executed the incorrect number of SQL statements. " + " expected: " + (EXPECTED_INDIRECTION_STATEMENTS - EXPECTED_INITIAL_STATEMENTS) + " got: " + (postIndirectionTriggerSQLStatements - EXPECTED_INITIAL_STATEMENTS));
        }
        if (postSecondQuerySQLStatements != EXPECTED_SECOND_QUERY_STATEMENTS) {
            throw new TestErrorException("Rerunning a ReadAllQuery with joining and triggering indirection executed the incorrect number of SQL statements. " + " expected: " + (EXPECTED_SECOND_QUERY_STATEMENTS - EXPECTED_INDIRECTION_STATEMENTS) + " got: " + (postSecondQuerySQLStatements - EXPECTED_INDIRECTION_STATEMENTS));
        }
        if (initialQueries != EXPECTED_INITIAL_QUERIES) {
            throw new TestErrorException("A ReadAllQuery with batching executed an incorrect number of Queries. " + " expected: " + EXPECTED_INITIAL_QUERIES + " got: " + initialQueries);
        }
        if (postIndirectionTriggerQueries != EXPECTED_INDIRECTION_QUERIES) {
            throw new TestErrorException("Triggering indirection on a batch read attribute executed the incorrect number of Queries. " + " expected: " + (EXPECTED_INDIRECTION_QUERIES - EXPECTED_INITIAL_QUERIES) + " got: " + (postIndirectionTriggerQueries - EXPECTED_INITIAL_QUERIES));
        }
        if (postSecondQueryQueries != EXPECTED_SECOND_QUERY_STATEMENTS) {
            throw new TestErrorException("Rerunning a ReadAllQuery with batch and triggering indirection executed the incorrect number of Queries. " + " expected: " + (EXPECTED_SECOND_QUERY_QUERIES - EXPECTED_INDIRECTION_QUERIES) + " got: " + (postSecondQueryQueries - EXPECTED_INDIRECTION_QUERIES));
        }
    }

    @Override
    public void reset() {
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
        tracker.remove();
    }
}
