/*
 * 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 checkCustomQueryRaceConditionsInReadObjectQuery.
     */
    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 method   {@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);
            }
        }

    }

}
