/*
 * 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 org.eclipse.persistence.testing.framework.TestCase;
import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.framework.TestWarningException;;


/**
 * This tests Oracle's Rownum filtering feature, using a query with MaxRows and FirstResults set
 */
public class RownumFilteringQueryTest extends TestCase{
    protected QuerySQLTracker tracker = null;
    protected int resultSize;

    protected int maxRows, firstResult;
    protected int expectedResultSize;
    protected String queryString = null;
    protected ReadQuery queryToUse;

    public RownumFilteringQueryTest() {
        firstResult = 1;
        maxRows = 2;
        expectedResultSize = 1;
    }

    public RownumFilteringQueryTest(Class classToQuery) {
        this();
        queryToUse = new ReadAllQuery(classToQuery);
    }

    public RownumFilteringQueryTest(int maxRows, int firstResult, int expectedResultSize) {
        this.firstResult = firstResult;
        this.maxRows = maxRows;
        this.expectedResultSize = expectedResultSize;
    }

    @Override
    public void setup() {
        DatabaseSession session = (DatabaseSession)getSession();
        DatabasePlatform platform = getSession().getPlatform();

        if ( !platform.isOracle() ) {
            throw new TestWarningException("Oracle Pagination not supported on platform " + platform);
        }
        tracker = new QuerySQLTracker(session);
    }

    @Override
    public void reset() {
        tracker.remove();
        queryString= null;
    }


    @Override
    public void test() {
        queryString= null;
        resultSize = 0;
        ReadQuery query = (ReadQuery)getQuery().clone();
        //query.addJoinedAttribute("address");
        query.setMaxRows(maxRows);
        query.setFirstResult(firstResult);
        resultSize = ((java.util.Vector)getSession().executeQuery(query)).size();
        java.util.List alist = tracker.getSqlStatements();
        int size = alist.size();
        if (size>0){
            queryString = (String)alist.get(size-1);
        }

    }

    @Override
    public void verify() {
        if ( resultSize != expectedResultSize){
            throw new TestErrorException("A ReadAllQuery with MaxRows="+maxRows+",FirstResult="+firstResult+" returned "+
                resultSize+" result(s) when "+expectedResultSize+" result(s) were expected.");
        }
        if ( queryString==null){
            throw new TestErrorException("A ReadAllQuery with MaxRows="+maxRows+",FirstResult="+firstResult+" did not generate an SQL string.");
        }
        int firstSelectIndex = queryString.indexOf("SELECT");
        int lastSelectIndex = queryString.lastIndexOf("SELECT");
        int firstRowNumIndex = queryString.indexOf("ROWNUM");
        int LastRowNumIndex = queryString.lastIndexOf("ROWNUM");
        if ( (firstSelectIndex == lastSelectIndex) || (firstRowNumIndex ==LastRowNumIndex) ){
            throw new TestErrorException("A ReadAllQuery with MaxRows="+maxRows+",FirstResult="+firstResult
                    +" did not generate proper SQL string Using Oracle pagination feature.");
        }
    }

    public ReadQuery getQuery(){
        if (queryToUse ==null){
            queryToUse = new ReadAllQuery(Employee.class);
        }
        return queryToUse;
    }

    public void getQuery(ReadQuery queryToUse){
        this.queryToUse = queryToUse;
    }

}
