/*
 * 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.querycache;

import java.util.*;

import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.testing.tests.optimization.queryandsqlcounting.*;
import org.eclipse.persistence.testing.framework.TestCase;
import org.eclipse.persistence.testing.framework.TestErrorException;

/**
 * Bug 6138532 - QUERY RESULTS CACHE SHOULD NOT STORE NULL FOR MULTIPLE RESULTS
 * Bug 6135563 - DATAREADQUERY QUERY RESULTS CACHE DOES NOT CACHE QUERY RESULTS
 * Responsibilities:
 * - Test that database queries do not go to the database, even if a "no results" query is cached
 * - Test that "no results" queries are cached for single and multiple value results
 * - Ensure that query results are cached, and no additional database hits are performed
 */
public class QueryCacheHitTest extends TestCase {

    private String testType;
    protected QuerySQLTracker tracker = null;

    public static final String NO_RESULTS_CACHED_READALL = "testNoResultsCachedReadAll";
    public static final String VALID_RESULTS_CACHED_READALL = "testValidResultsCachedReadAll";
    public static final String NO_RESULTS_CACHED_READOBJECT = "testNoResultsCachedReadObject";
    public static final String VALID_RESULTS_CACHED_READOBJECT = "testValidResultsCachedReadObject";
    public static final String NO_RESULTS_CACHED_DATAREAD = "testNoResultsCachedDataRead";
    public static final String VALID_RESULTS_CACHED_DATAREAD = "testValidResultsCachedDataRead";

    public QueryCacheHitTest(String testType) {
        super();
        this.testType = testType;
        setDescription("Test to ensure that the database is not hit for queries that are cached, including cached zero results.");
    }

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

    @Override
    public void test() {
        if (testType == NO_RESULTS_CACHED_DATAREAD) {
            testNoResultsCachedDataRead();
        } else if (testType == NO_RESULTS_CACHED_READALL) {
            testNoResultsCachedReadAll();
        } else if (testType == VALID_RESULTS_CACHED_READALL) {
            testValidResultsCachedReadAll();
        } else if (testType == NO_RESULTS_CACHED_READOBJECT) {
            testNoResultsCachedReadObject();
        } else if (testType == VALID_RESULTS_CACHED_READOBJECT) {
            testValidResultsCachedReadObject();
        } else if (testType == NO_RESULTS_CACHED_DATAREAD) {
            testNoResultsCachedDataRead();
        } else if (testType == VALID_RESULTS_CACHED_DATAREAD) {
            testValidResultsCachedDataRead();
        } else {
            throw new TestErrorException("Invalid test type (" + testType + ") passed");
        }
    }

    public void testNoResultsCachedReadAll() {
        ReadAllQuery query = new ReadAllQuery(Employee.class);
        ExpressionBuilder builder = query.getExpressionBuilder();
        Expression exp = builder.get("firstName").like(builder.getParameter("fName"));
        query.setSelectionCriteria(exp);
        query.addArgument("fName");
        query.setQueryResultsCachePolicy(new QueryResultsCachePolicy(2));

        // Test ReadAllQuery with zero expected results ("no results" cached)
        // Do not go to the database if "no results" is cached
        Vector params = new Vector(1);
        params.add("impossiblefirstname");

        for (int i = 0; i < 3; i++) {
            Vector results = (Vector) getSession().executeQuery(query, params);
            // assert that we do not get null back from the cache for "no results"
            assertNotNull(results);
            if (results != null) {
                // assert that we do not have any DB results (from cache)
                assertTrue(results.isEmpty());
            }
            // assert that the database was only hit once (important)
            assertEquals(tracker.getSqlStatements().size(), 1);
        }
    }

    public void testValidResultsCachedReadAll() {
        ReadAllQuery query = new ReadAllQuery(Employee.class);
        ExpressionBuilder builder = query.getExpressionBuilder();
        Expression exp = builder.get("firstName").like(builder.getParameter("fName"));
        query.setSelectionCriteria(exp);
        query.addArgument("fName");
        query.setQueryResultsCachePolicy(new QueryResultsCachePolicy(2));

        Vector params = new Vector(1);
        params.add("B%");

        for (int i = 0; i < 3; i++) {
            Vector results = (Vector) getSession().executeQuery(query, params);
            // assert that we do not get null back from the cache
            assertNotNull(results);
            if (results != null) {
                // assert that we get back DB results (from cache)
                assertTrue(!results.isEmpty());
            }
            // assert that the database was only hit once (important)
            assertEquals(tracker.getSqlStatements().size(), 1);
        }
    }

    public void testNoResultsCachedReadObject() {
        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        ExpressionBuilder builder2 = query.getExpressionBuilder();
        Expression exp2 = builder2.get("lastName").like(builder2.getParameter("lName"));
        query.setSelectionCriteria(exp2);
        query.addArgument("lName");
        query.setQueryResultsCachePolicy(new QueryResultsCachePolicy(2));

        // Do not go to the database if "no results" is cached
        Vector params = new Vector(1);
        params.add("impossiblelastname");

        for (int i = 0; i < 3; i++) {
            Object result = getSession().executeQuery(query, params);
            assertNull(result);
            // assert that the database was only hit once (important)
            assertEquals(tracker.getSqlStatements().size(), 1);
        }
    }

    public void testValidResultsCachedReadObject() {
        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        ExpressionBuilder builder2 = query.getExpressionBuilder();
        Expression exp2 = builder2.get("lastName").like(builder2.getParameter("lName"));
        query.setSelectionCriteria(exp2);
        query.addArgument("lName");
        query.setQueryResultsCachePolicy(new QueryResultsCachePolicy(2));

        Vector params = new Vector(1);
        params.add("Smith");

        for (int i = 0; i < 3; i++) {
            Object result = getSession().executeQuery(query, params);
            // assert that we do not get null back from the cache
            assertNotNull(result);
            // assert that the database was only hit once (important)
            assertEquals(tracker.getSqlStatements().size(), 1);
        }
    }

    public void testNoResultsCachedDataRead() {
        DataReadQuery dataReadQuery1 = new DataReadQuery();
        String sqlString1 = "SELECT F_NAME, L_NAME FROM EMPLOYEE WHERE F_NAME = 'impossible'";
        dataReadQuery1.setSQLString(sqlString1);
        dataReadQuery1.setQueryResultsCachePolicy(new QueryResultsCachePolicy(2));
        // Test DataReadQuery with zero expected results ("no results" cached)
        // Do not go to the database if "no results" is cached

        for (int i = 0; i < 3; i++) {
            Vector results = (Vector) getSession().executeQuery(dataReadQuery1);
            // assert that we do not get null back from the cache for "no results"
            assertNotNull(results);
            if (results != null) {
                // assert that we do not have any DB results (from cache)
                assertTrue(results.isEmpty());
            }
            // assert that the database was only hit once (important)
            assertEquals(tracker.getSqlStatements().size(), 1);
        }
    }

    public void testValidResultsCachedDataRead() {
        DataReadQuery dataReadQuery2 = new DataReadQuery();
        String sqlString2 = "SELECT F_NAME, L_NAME FROM EMPLOYEE";
        dataReadQuery2.setSQLString(sqlString2);
        dataReadQuery2.setQueryResultsCachePolicy(new QueryResultsCachePolicy(2));

        for (int i = 0; i < 3; i++) {
            Vector results = (Vector) getSession().executeQuery(dataReadQuery2);
            // assert that we do not get null back from the cache
            assertNotNull(results);
            if (results != null) {
                // assert that we get back DB results (from cache)
                assertTrue(!results.isEmpty());
            }
            // assert that the database was only hit once (important)
            assertEquals(tracker.getSqlStatements().size(), 1);
        }
    }

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

}
