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

import java.lang.reflect.Method;
import java.sql.*;
import java.util.Map;

import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.models.employee.domain.Address;

/**
 * This tests the use of batch writing for a large number of inserts.
 */
public class CacheStatementBatchWritingTest extends TransactionalTestCase {
    protected static int NUM_INSERTS = 102;
    protected boolean shouldCacheStatements;
    protected boolean shouldBindAllParams;

    public CacheStatementBatchWritingTest() {
        setDescription("Tests a large number of inserts using Batch Writing, verifies that statement cacheing is used");
    }

    @Override
    public void setup() {
        super.setup();
        this.shouldCacheStatements = getSession().getPlatform().shouldCacheAllStatements();
        this.shouldBindAllParams = getSession().getPlatform().shouldBindAllParameters();
        getSession().getPlatform().setShouldCacheAllStatements(true);
        getSession().getPlatform().setShouldBindAllParameters(true);
        //clear the statement cache for bug 245003
        ((DatabaseAccessor)getAbstractSession().getAccessor()).clearStatementCache((AbstractSession)getSession());
    }

    @Override
    public void reset() {
        super.reset();
        getSession().getPlatform().setShouldCacheAllStatements(this.shouldCacheStatements);
        getSession().getPlatform().setShouldBindAllParameters(this.shouldBindAllParams);
        ((DatabaseAccessor)getAbstractSession().getAccessor()).clearStatementCache((AbstractSession)getSession());
    }

    @Override
    public void test() {
        Address address;
        UnitOfWork uow = getSession().acquireUnitOfWork();
        for (int i = 0; i < NUM_INSERTS; i++) {
            address = new Address();
            address.setCity("city" + i);
            address.setProvince("province" + i);
            uow.registerObject(address);
        }
        uow.commit();
        //a little hack to force the remaining SQL to go to the Database
        ((DatabaseAccessor)uow.getParent().getAccessor()).getActiveBatchWritingMechanism(getAbstractSession()).executeBatchedStatements(uow.getParent());

        //get statement
        PreparedStatement statement = null;
        Map statementCache = null;
        String sql = getSession().getDescriptor(Address.class).getQueryManager().getInsertQuery().getSQLString();
        try {
            Method method = uow.getParent().getAccessor().getClass().getDeclaredMethod("getStatementCache", new Class[] { });
            method.setAccessible(true);
            statementCache = (Map)method.invoke(uow.getParent().getAccessor(), new Object[] { });
            statement =  (PreparedStatement)statementCache.get(sql);
        } catch (Exception ex) {
            throw new TestErrorException("Failed to run test. Check java.policy file \"SupressAccessChecks\" perission required :" +
                                         ex.toString());
        }
        try {
            statement.close();
        } catch (SQLException ex) {
            throw new TestErrorException("Failed on modifying the statementCache");
        }
        //run again and verify the same statement.
        uow = getSession().acquireUnitOfWork();
        for (int i = 0; i < NUM_INSERTS; i++) {
            address = new Address();
            address.setCity("city" + (i + NUM_INSERTS));
            address.setProvince("province" + (i + NUM_INSERTS));
            uow.registerObject(address);
        }
        try {
            uow.commit();
            //a little hack to force the remaining SQL to go to the Database
            ((DatabaseAccessor)uow.getParent().getAccessor()).getActiveBatchWritingMechanism(getAbstractSession()).executeBatchedStatements(uow.getParent());
        } catch (Exception ex) {
            return; // if the exception is thrown then TopLink is caching correctly
        } finally {
            //removed the closed connection
            statementCache.remove(sql);
        }
        throw new TestErrorException("Statements were not cached correctly");
    }
}
