/*
 * Copyright (c) 2015, 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:
//    04/20/2015-2.7 Tomas Kraus - Concurrency test to trigger NPE in
//                                 checkForCustomQuery(AbstractSession, AbstractRecord).
package org.eclipse.persistence.testing.tests.queries;

import static org.eclipse.persistence.logging.SessionLog.INFO;
import static org.eclipse.persistence.logging.SessionLog.WARNING;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.queries.SQLCall;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.testing.framework.TestCase;
import org.eclipse.persistence.testing.models.employee.domain.Employee;

/**
 * Test read queries using objects.
 */
public abstract class ObjectLevelReadQueryTest extends TestCase {

    /** Fail message for NPE in checkForCustomQuery method. */
    private static final String FAIL_NPE
        = "NullPointerException thrown in checkForCustomQuery(AbstractSession, AbstractRecord)";

    /** Logger used in test. */
    protected SessionLog log;

    /** Current database session. */
    protected Session session;

    /** Some entity to be used in query. */
    protected final Class entity = Employee.class;

    /** Some SQL call to be used in query. */
    protected final SQLCall call = new SQLCall("SELECT t0.EMP_ID FROM EMPLOYEE t0");

    /**
     * Creates an instance of jUnit tests for read queries using objects.
     */
    public ObjectLevelReadQueryTest() {
        super();
    }

    /**
     * Creates an instance of jUnit tests for read queries using objects.
     * @param name jUnit test name.
     */
    public ObjectLevelReadQueryTest(final String name) {
        super();
        setName(name);
    }

    /**
     * Initialize this test suite.
     */
    @Override
    public void setup() {
        session = getSession();
        log = session.getSessionLog();
    }

    /**
     * Clean this test suite.
     */
    @Override
    public void reset() {
        session = null;
        log = null;
    }

    /**
     * {@link TestCase#test()} method overwritten as public to avoid failures.
     */
    @Override
    public abstract void test() throws Throwable;

    /**
     * {@code [ObjectLevelReadQuery].isCustomQueryUsed} value changer
     * for {@link #testCheckForCustomQueryRaceConditions()}.
     */
    private static final class ValueChanger extends Thread {

        /** Logger used in test. */
        private final SessionLog log;

        /** Query where to change {@code isCustomQueryUsed} value. */
        private final ObjectLevelReadQuery query;

        /** Instance used for synchronization. */
        private final Object mutex;

        /** [ObjectLevelReadQuery].isCustomQueryUsed} field. */
        private final Field isCustomQueryUsed;

        /** Thread execution flag. */
        private boolean execute;

        /**
         * Creates an instance of value changer thread.
         * @param objectLevelReadQuery Query object where {@code isCustomQueryUsed} value will be changed.
         * @param syncMutex            Instance used for synchronization.
         * @param sessionLog           Logger used in test.
         */
        private ValueChanger(final ObjectLevelReadQuery objectLevelReadQuery, final Object syncMutex,
                final SessionLog sessionLog) {
            log = sessionLog;
            // Calling run() directly will do nothing.
            query = objectLevelReadQuery;
            mutex = syncMutex;
            execute = false;
            // Placeholder for initialization.
            Field isCustomQueryUsedLocal;
            try {
                isCustomQueryUsedLocal = DatabaseQuery.class.getDeclaredField("isCustomQueryUsed");
            } catch (NoSuchFieldException | SecurityException e) {
                log.logThrowable(WARNING, e);
                isCustomQueryUsedLocal = null;
            }
            if (isCustomQueryUsedLocal != null) {
                try {
                    isCustomQueryUsedLocal.setAccessible(true);
                } catch (SecurityException e) {
                    log.logThrowable(WARNING, e);
                    isCustomQueryUsedLocal = null;
                }
            }
            isCustomQueryUsed = isCustomQueryUsedLocal;
        }

        /**
         * Check if value changer initialization was successful.
         * @return Value of {@code true} when {@code isCustomQueryUsed} field is available or {@code false} otherwise.
         */
        private boolean isOk() {
            return isCustomQueryUsed != null;
        }

        /**
         * Start thread execution.
         */
        @Override
        public void start() {
            execute = true;
            super.start();
        }

        /**
         * Request thread to finish.
         */
        public void finish() {
            execute = false;
        }

        /**
         * Thread code to be executed.
         */
        @Override
        public void run() {
            synchronized(mutex) {
                mutex.notify();
            }
            while(execute) {
                try {
                    isCustomQueryUsed.set(query, Boolean.TRUE);
                    isCustomQueryUsed.set(query, null);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    log.logThrowable(WARNING, e);
                    execute = false;
                }
            }
        }
    }

    /**
     * Get {@code [ObjectLevelReadQuery].checkForCustomQuery(AbstractSession, AbstractRecord)} method accessor.
     * @param c Class where to search for method.
     * @return {@code [ObjectLevelReadQuery].checkForCustomQuery(AbstractSession, AbstractRecord)} method accessor.
     */
    protected Method getCheckForCustomQueryMethod(final Class c) {
        Method method;
        try {
            method = c.getDeclaredMethod(
                    "checkForCustomQuery", AbstractSession.class, AbstractRecord.class);
            method.setAccessible(true);
        } catch (NoSuchMethodException | SecurityException e) {
            log.logThrowable(WARNING, e);
            method = null;
        }
        return method;
    }

    /**
     * Call {@code [ObjectLevelReadQuery].checkForCustomQuery(AbstractSession, AbstractRecord)} method.
     * @param instance ObjectLevelReadQuery instance on which method is called.
     * @param mathod   {@code [ObjectLevelReadQuery].checkForCustomQuery(AbstractSession, AbstractRecord)}
     *                 method accessor.
     * @throws Throwable when any exception except NPE in invoked method occurs.
     */
    protected DatabaseQuery callCheckForCustomQueryMethod(final Object instance, final Method method) throws Throwable {
        DatabaseQuery databaseQuery;
        try {
            databaseQuery = (DatabaseQuery)method.invoke(instance, session, null);
        } catch (InvocationTargetException e) {
            if (e.getTargetException() instanceof NullPointerException) {
                log.log(WARNING, FAIL_NPE);
                e.printStackTrace();
                fail(FAIL_NPE);
            }
            log.logThrowable(WARNING, e);
            throw e;
        } catch (Throwable e) {
            log.logThrowable(WARNING, e);
            e.printStackTrace();
            throw e;
        }
        return databaseQuery;
    }

    /**
     * jUnit test to verify NPE in {@code checkForCustomQuery} method in {@link ReadAllQuery} class.
     */
    public static final class CustomQueryRaceConditionsInReadAllQueryTest extends ObjectLevelReadQueryTest {

        /**
         * Creates an instance of jUnit test.
         */
        public CustomQueryRaceConditionsInReadAllQueryTest() {
            super();
        }

        /**
         * Creates an instance of jUnit test.
         * @param name jUnit test name.
         */
        public CustomQueryRaceConditionsInReadAllQueryTest(final String name) {
            super(name);
        }

        /**
         * Test {@code [ReadAllQuery].checkForCustomQuery(AbstractSession, AbstractRecord)}
         * when {@code isCustomQueryUsed} is changed to null during query execution.
         * Reproduction scenario for bug# 436871 which works with high enough probability.
         * @throws Throwable when any exception except NPE in checkForCustomQuery occurs.
         */
        @Override
        public void test() throws Throwable {
            log.log(INFO, "Running checkCustomQueryRaceConditionsInReadAllQuery test.");
            final Method checkForCustomQuery = getCheckForCustomQueryMethod(ObjectLevelReadQuery.class);
            final ReadAllQuery query = new ReadAllQuery(entity, call);
            final Object mutex = new Object();
            final ValueChanger changer = new ValueChanger(query, mutex, log);
            assertTrue("Initialization of isCustomQueryUsed property value changer failed.", changer.isOk());
            try {
                synchronized (mutex) {
                    changer.start();
                    mutex.wait();
                }
            } catch (InterruptedException e) {
                log.logThrowable(WARNING, e);
            }
            query.setReferenceClass(entity);
            query.setDescriptor(session.getDescriptor(entity));
            // 100 iterations is enough to get exception in almost 100% of tests.
            for (int i = 0; i < 100; i++)
                callCheckForCustomQueryMethod(query, checkForCustomQuery);
            changer.finish();
            try {
                changer.join();
            } catch (InterruptedException e) {
                log.logThrowable(WARNING, e);
            }
        }

    }

    /**
     * jUnit test to verify NPE in {@code checkForCustomQuery} method in {@link ReadObjectQuery} class.
     */
    public static final class CustomQueryRaceConditionsInReadObjectQueryTest extends ObjectLevelReadQueryTest {

        /**
         * Creates an instance of jUnit test.
         */
        public CustomQueryRaceConditionsInReadObjectQueryTest() {
            super();
        }

        /**
         * Creates an instance of jUnit test.
         * @param name jUnit test name.
         */
        public CustomQueryRaceConditionsInReadObjectQueryTest(final String name) {
            super(name);
        }

        /**
         * Test {@code [ReadObjectQuery].checkForCustomQuery(AbstractSession, AbstractRecord)}
         * when {@code isCustomQueryUsed} is changed to null during query execution.
         * Reproduction scenario for bug# 436871 which works with high enough probability.
         * @throws Throwable when any exception except NPE in {@code  checkForCustomQuery} occurs.
         */
        @Override
        public void test() throws Throwable {
            log.log(INFO, "Running checkCustomQueryRaceConditionsInReadObjectQuery test.");
            final Method checkForCustomQuery = getCheckForCustomQueryMethod(ObjectLevelReadQuery.class);
            final ReadObjectQuery query = new ReadObjectQuery(entity, call);
            final Object mutex = new Object();
            final ValueChanger changer = new ValueChanger(query, mutex, log);
            assertTrue("Initialization of isCustomQueryUsed property value changer failed.", changer.isOk());
            try {
                synchronized (mutex) {
                    changer.start();
                    mutex.wait();
                }
            } catch (InterruptedException e) {
                log.logThrowable(WARNING, e);
            }
            query.setReferenceClass(entity);
            query.setDescriptor(session.getDescriptor(entity));
            // 100 iterations is enough to get exception in almost 100% of tests.
            for (int i = 0; i < 100; i++)
                callCheckForCustomQueryMethod(query, checkForCustomQuery);
            changer.finish();
            try {
                changer.join();
            } catch (InterruptedException e) {
                log.logThrowable(WARNING, e);
            }
        }

    }

}
