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

import java.io.IOException;
import java.io.Writer;
import java.lang.ref.WeakReference;

import jakarta.persistence.EntityManager;

import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEventAdapter;
import org.eclipse.persistence.sessions.server.Server;
import org.eclipse.persistence.sessions.server.ServerSession;

/**
 * <p>Purpose<b></b>:
 * All the test cases are subclassed from this class.
 * Each test case tests single feature of TopLink. Ideally a test case consists of five steps.
 * Setup: Performs all the initial setup that is required by the test,
 * such as setting up database to some state on which test would run.
 * Test: The actual test to be performed, such as writing an object.
 * Verify: Verify the test if it was performed well or not.
 * Reset: Reset the database to the state from where the test started
 * Reset Verify: Check if reset performed well or not.
 */
public abstract class TestCase extends junit.framework.TestCase implements TestEntity {

    /** Store the name to allow serialization, for some reason JUnit name does not serialize. */
    private String name;

    /** The result of the test. */
    private TestResult testResult;

    /** The executor used to execute the test. */
    private transient TestExecutor executor;

    /** To provide small description of the test case */
    private String description;

    /** The test collection that contains this test */
    private TestEntity container;

    /** This is used only for printing test results with proper indentation */
    private int nestedCounter;

    /** The indentation string that is added to each line of result for printing. */
    private String indentationString;

    public TestCase() {
        description = "";
        nestedCounter = INITIAL_VALUE;
        testResult = new TestResult(this);
        setName(getClass().getName().substring(getClass().getName().lastIndexOf('.') + 1));
    }

    /**
     * Reset the JUnit name in case serialization looses it.
     */
    @Override
    public String getName() {
        if (super.getName() == null) {
            setName(this.name);
        }
        return super.getName();
    }

    /**
     * Store the test name locally to ensure it can serialize.
     */
    @Override
    public void setName(String name) {
       super.setName(name);
       this.name = name;
    }

    /**
     * Append test case result to the test results summary.
     */
    @Override
    public void appendTestResult(TestResultsSummary summary) {
        summary.appendTestCaseResult(this);
    }

    /**
     * Computes the level for indentation.
     */
    @Override
    public void computeNestedLevel() {
        TestEntity testContainer = getContainer();

        if ((testContainer != null) && (testContainer.getNestedCounter() != INITIAL_VALUE)) {
            setNestedCounter(testContainer.getNestedCounter() + 1);
        } else {
            incrementNestedCounter();
        }
    }

    /**
     * Return if the two objects match.
     */
    public boolean compareObjects(Object source, Object target) {
        return getAbstractSession().compareObjects(source, target);
    }

    /**
     * Check the database and ensure the object and its parts have been fully deleted.
     */
    public boolean verifyDelete(Object object) {
        return getAbstractSession().verifyDelete(object);
    }

    /**
     * The session is initialized to the default login from the Persistent System
     * if no explicit login is done for testing. This method must be overridden in
     * the subclasses if different login is required.
     */
    @Override
    public Session defaultLogin() {
        return (new TestSystem()).login();
    }

    /**
     * Executes this test case.
     * Note:
     * Only RuntimeExceptions are caught because all EclipseLink Exceptions are derived from
     * RuntimeException. This takes care of other java runtime exceptions also.
     */
    @Override
    public void execute(TestExecutor executor) {
        boolean executeFailed = false;
        setTestResult(new TestResult(this, "Passed"));
        setExecutor(executor);

        long startTime = System.nanoTime();
        try {
            try {
                setUp();
            } catch (EclipseLinkException exception) {
                executeFailed = true;
                setTestException(exception);
                throw exception;
            } catch (Throwable exception) {
                executeFailed = true;
                TestProblemException problem = new TestProblemException("Problem in the setup method of the test: " + getName());
                problem.setInternalException(exception);
                setTestException(problem);
                throw problem;
            }

            try {
                executeTest();
                verify();
            } catch (EclipseLinkException exception) {
                executeFailed = true;
                if (getTestException() == null) {
                    setTestException(exception);
                    throw exception;
                }
            } catch (Throwable runtimeException) {
                executeFailed = true;
                TestErrorException topLinkException = new TestErrorException("Fatal error occurred.", runtimeException);
                if (getTestException() == null) {
                    setTestException(topLinkException);
                    throw topLinkException;
                }
            }
        } finally {
            try {
                tearDown();
            } catch (EclipseLinkException exception) {
                executeFailed = true;
                if (getTestException() == null) {
                    setTestException(exception);
                    throw exception;
                }
            } catch (Throwable exception) {
                executeFailed = true;
                TestProblemException problem = new TestProblemException("Problem in the reset method of the test");
                problem.setInternalException(exception);
                if (getTestException() == null) {
                    setTestException(problem);
                    throw problem;
                }
            } finally {
                long endTime = System.nanoTime();
                getTestResult().setTotalTime(endTime - startTime);

                // If a failure occurred allow recreation of the database and initialize the identity maps.
                if (executeFailed) {
                    // If this test is not local allow for cleanup.
                    if (!isLocalTest()) {
                        cleanAfterExecuteFailed();
                    }
                }

                // Check for faulty tests leaving transaction open.
                if (getAbstractSession().isInTransaction()) {
                    try {
                        int count = 0;
                        while (getAbstractSession().isInTransaction() && (count < 10)) {
                            getAbstractSession().rollbackTransaction();
                            count++;
                        }
                    } catch (Throwable ignore) {
                    }
                    TestProblemException problem = new TestProblemException(this + " is a faulty test, transaction was left open and must always be closed.");
                    problem.setInternalException(getTestException());
                    setTestException(problem);
                    throw problem;
                }
            }
        }
    }

    /**
     * Sets up the fixture, for example, open a network connection.
     * This method is called before a test is executed.
     * Calls old setup method by default.
     */
    @Override
    protected void setUp() throws Exception {
        try {
            setup();
        } catch (Throwable exception) {
            if (exception instanceof Exception) {
                throw (Exception)exception;
            } else {
                throw new TestErrorException("Fatal errored in setUp.", exception);
            }
        }
    }

    /**
     * Tears down the fixture, for example, close a network connection.
     * This method is called after a test is executed.
     * Calls old reset method by default.
     */
    @Override
    protected void tearDown() throws Exception {
        try {
            reset();
            resetVerify();
        } catch (Throwable exception) {
            if (exception instanceof Exception) {
                throw (Exception)exception;
            } else {
                throw new TestErrorException("Fatal errored in tearDown.", exception);
            }
        }
    }

    /**
     * If there is no executor,
     * Create a default executor and run the test.
     */
    @Override
    public void runBare() throws Throwable {
        TestExecutor executor = getExecutor();
        if (executor == null) {
            executor = TestExecutor.getDefaultExecutor();
        }
        try {
            execute(executor);
        } catch (TestWarningException exception) {
            System.out.println("WARNING: " + exception);
        }
    }

    /**
     * Return test collection which contains this test entity.
     */
    @Override
    public TestEntity getContainer() {
        return container;
    }

    /**
     * Return the description of the test.
     */
    public String getDescription() {
        return description;
    }

    /**
     * Return the executor.
     */
    public TestExecutor getExecutor() {
        return executor;
    }

    /**
     * Get the indentaitonString
     */
    public String getIndentationString() {
        return indentationString;
    }

    /**
     * Return the nested counter value
     */
    @Override
    public int getNestedCounter() {
        return nestedCounter;
    }

    /**
     * Return the test result. The testResult stores the result of this
     * test.
     */
    @Override
    public ResultInterface getReport() {
        return getTestResult();
    }

    /**
     * Create a new entity manager from the entity manager factory.
     * This entity manager is initialized from META-INF/persistence.xml.
     */
    public EntityManager createEntityManager() {
        return getExecutor().createEntityManager();
    }

    /**
     * Return the session cast to DatabaseSession.
     */
    public org.eclipse.persistence.sessions.DatabaseSession getDatabaseSession() {
        return (org.eclipse.persistence.sessions.DatabaseSession)getExecutor().getSession();
    }

    /**
     * Return the session cast to AbstractSession.
     */
    public org.eclipse.persistence.internal.sessions.AbstractSession getAbstractSession() {
        return (org.eclipse.persistence.internal.sessions.AbstractSession)getExecutor().getSession();
    }

    /**
     * Return the database session.
     */
    public org.eclipse.persistence.sessions.Session getSession() {
        return getExecutor().getSession();
    }

    /**
     * Return and cast the session to a Server.
     */
    public Server getServerSession() {
        return (Server)getExecutor().getSession();
    }

    /**
     * Begin a transaction, cast to AbstractSession to work with all session types.
     */
    public void beginTransaction() {
        getAbstractSession().beginTransaction();
    }

    /**
     * Commit a transaction, cast to AbstractSession to work with all session types.
     */
    public void commitTransaction() {
        getAbstractSession().commitTransaction();
    }

    /**
     * Rollback a transaction, cast to AbstractSession to work with all session types.
     */
    public void rollbackTransaction() {
        getAbstractSession().rollbackTransaction();
    }

    public EclipseLinkException getTestException() {
        return getTestResult().getException();
    }

    /**
     * Return the test result. The testResult stores the result of this
     * test.
     */
    public TestResult getTestResult() {
        return testResult;
    }

    @Override
    public void incrementNestedCounter() {
        setNestedCounter(getNestedCounter() + 1);
    }

    /**
     * The result of the test is logged on to the specified print stream.
     * This method is added to migrate tests to Ora*Tst
     */
    @Override
    public void logRegressionResult(Writer log) {
        computeNestedLevel();
        setIndentationString(Helper.getTabs(getNestedCounter()));

        try {
            log.write(org.eclipse.persistence.internal.helper.Helper.cr() + getIndentationString() + "TEST NAME:   " + getName() + org.eclipse.persistence.internal.helper.Helper.cr());
            log.write(getIndentationString() + "TEST DESCRIPTION: " + getDescription() + org.eclipse.persistence.internal.helper.Helper.cr());
            log.flush();
        } catch (IOException exception) {
        }
        getTestResult().logRegressionResult(log);
    }

    /**
     * The result of the test is logged on to the specified print stream.
     */
    @Override
    public void logResult(Writer log, boolean shouldLogOnlyErrors) {
        logResult(log);
    }

    /**
     * The result of the test is logged on to the specified print stream.
     */
    @Override
    public void logResult(Writer log) {
        computeNestedLevel();
        setIndentationString(Helper.getTabs(getNestedCounter()));

        try {
            log.write(org.eclipse.persistence.internal.helper.Helper.cr() + getIndentationString() + "VERSION:   " + org.eclipse.persistence.sessions.DatabaseLogin.getVersion());
            log.write(org.eclipse.persistence.internal.helper.Helper.cr() + getIndentationString() + "TEST NAME:   " + getName() + org.eclipse.persistence.internal.helper.Helper.cr());
            log.write(getIndentationString() + "TEST DESCRIPTION: " + getDescription() + org.eclipse.persistence.internal.helper.Helper.cr());
            log.flush();
        } catch (IOException exception) {
        }
        getTestResult().logResult(log);
    }

    @Override
    public boolean requiresDatabase() {
        return true;
    }

    /**
     * This is a optional method in the test cases. It should be overridden only if somthing has to
     * be reset back to the state from where the test started.
     */
    public void reset() throws Throwable {
        return;
    }

    /**
     * Reset the entity.
     */
    @Override
    public void resetEntity() {
        try {
            reset();
        } catch (Throwable runtimeException) {
            TestProblemException validationException = new TestProblemException("Reset problem occurred.", runtimeException);
            if (getTestException() == null) {
                setTestException(validationException);
            }
            throw validationException;
        }
    }

    @Override
    public void resetNestedCounter() {
        setNestedCounter(INITIAL_VALUE);
    }

    /**
     * This is a mandatory method in the test cases only if reset has been overridden.
     * The method should check if reset method really reset the databse back to the state
     * from where the test started.
     */
    protected void resetVerify() throws Throwable {
        return;
    }

    @Override
    public void setContainer(TestEntity testEntity) {
        container = testEntity;
    }

    /**
     * Set the description of the test.
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Set the executor.
     */
    public void setExecutor(TestExecutor anExecutor) {
        executor = anExecutor;
    }

    /**
     * Set the indentaitonString
     */
    public void setIndentationString(String indentationString) {
        this.indentationString = indentationString;
    }

    /**
     * Set the nested counter value.
     */
    @Override
    public void setNestedCounter(int level) {
        this.nestedCounter = level;
    }

    /**
     * The exception raised by the test is stored in the result. Eventually the result
     * decides the outcome of the test depending upon the kind of exception. No exception is
     * stored if test runs well.
     */
    public void setTestException(EclipseLinkException exception) {
        getTestResult().setException(exception);
    }

    /**
     * Set the test result.
     */
    @Override
    public void setReport(ResultInterface testResult) {
        setTestResult((TestResult)testResult);
    }

    /**
     * Set the test result. The testResult stores the result of the
     * test.
     */
    public void setTestResult(TestResult testResult) {
        this.testResult = testResult;
        testResult.setTestCase(this);
    }

    /**
     * The first step in testing process. The method is overridden if their is something
     * that test should perform before running the actual test.
     */
    protected void setup() throws Throwable {
        return;
    }

    /**
     * Override to run the test and assert its state.
     * @exception Throwable if any exception is thrown
     */
    @Override
    protected void runTest() throws Throwable {
        // Nothing by default.
    }

    /**
     * Allow for test to intercept running of test.
     */
    public void executeTest() throws Throwable {
        test();
    }

    /**
     * Test can be define as test, or runTest,
     * or if the name is a method on this class,
     * this method is run reflectively by default.
     */
    protected void test() throws Throwable {
        runTest();
    }

    /**
     * Print the test as its name.
     */
    public String toString() {
        return getName();
    }

    /**
     * Verification of test is done here if the test ran properly or not. Subclasses should
     * override it.
     */
    protected void verify() throws Throwable {
        return;
    }

    /**
     * Throw a test error exception.
     * Errors indicate the test failed.
     */
    public void throwError(String message) {
        throw new TestErrorException(message);
    }

    /**
     * Throw a test error exception.
     * Errors indicate the test failed.
     */
    public void throwError(String message, Throwable exception) {
        throw new TestErrorException(message, exception);
    }

    /**
     * Throw a test warning exception.
     * Warning indicate the test did not fail, but did not pass either,
     * the test could not be run or the result could not be verified.
     */
    public void throwWarning(String message) {
        throw new TestWarningException(message);
    }

    /**
     * Sometimes a test prefers to perform a number of small checks/assertions
     * in the test() method, rather than calling a single test() followed
     * by a single verify().
     * <p>
     * In line with JUNIT style testing, would be called assert if assert
     * did not become a reserved keyword in JDK 1.4.2.
     */
    public void strongAssert(boolean assertion, String errorMessage) {
        if (!assertion) {
            throw new TestErrorException(errorMessage);
        }
    }

    /**
     * Same as strongAssert but only throws a warning.  I.e. if the check
     * is how the feature is implemented but not really crucial to how it works,
     * just throw a warning and fix the test later.
     * @param assertion
     * @param warningMessage
     */
    public void weakAssert(boolean assertion, String warningMessage) {
        if (!assertion) {
            throw new TestWarningException(warningMessage);
        }
    }

    /**
     * Answer true to a local test check if the class name ends in "Local"
     */
    private boolean isLocalTest() {
        return getClass().getName().endsWith("Local");
    }

    /**
     * If the execute fails, do the necessary cleanup to ensure the next test gets no residue
     */
    public void cleanAfterExecuteFailed() {
    }

    /**
     * Throws a warning of pessimistic locking/select for update is not supported for this test platform.
     * Currently testing supports select for update on Oracle, MySQL, SQLServer, TimesTen.
     * Some of the other platforms may have some support for select for update, but the databases we test with
     * for these do not have sufficient support to pass the tests.
     * Derby, Firebird and Symfoware (bug 304903) have some support, but does not work with joins (2008-12-01).
     */
    public void checkSelectForUpateSupported() {
        DatabasePlatform platform = getSession().getPlatform();
        if (platform.isFirebird() || platform.isAccess() || platform.isSybase() || platform.isSQLAnywhere() || platform.isDerby() || platform.isHSQL() || platform.isSymfoware()) {
            throw new TestWarningException("This database does not support FOR UPDATE");
        }
    }

    /**
     * Throws a warning of pessimistic locking/select for update nowait is not supported for this test platform.
     * Currently testing supports nowait on Oracle, SQLServer, PostgreSQL.
     */
    public void checkNoWaitSupported() {
        DatabasePlatform platform = getSession().getPlatform();
        if (!(platform.isOracle() || platform.isSQLServer() || platform.isPostgreSQL())) {
            throw new TestWarningException("This database does not support NOWAIT");
        }
    }


    /**
     * Throws a warning if the test database is using serializable transaction isolation.
     */
    public SessionEventAdapter checkTransactionIsolation() {
        final SessionEventAdapter listener;
        DatabasePlatform platform = getSession().getPlatform();
        if (platform.isSybase()) {
            if (SybaseTransactionIsolationListener.isDatabaseVersionSupported((ServerSession) getAbstractSession().getParent())) {
                listener = new SybaseTransactionIsolationListener();
            } else {
                throw new TestWarningException("The test requires Sybase version " + SybaseTransactionIsolationListener.requiredVersion + " or higher");
            }
        } else if (platform.isSQLServer()) {
            throw new TestWarningException("This test requires transaction isolation setup on SQLServer database which is currently not set in tlsvrdb6");
        } else if (platform.isSQLAnywhere()) {
            throw new TestWarningException("This test requires transaction isolation setup on SQLAnywhere database which is currently not set");
        } else if (platform.isDB2()) {
            throw new TestWarningException("This test requires transaction isolation setup on DB2 database which is currently not set");
        } else if (platform.isDerby() || platform.isSymfoware()) {
            listener = new TransactionIsolationLevelSwitchListener(platform);
        } else if (platform.isMaxDB()) {
            listener = new JDBCIsoLevelSwitchListener();
        } else {
            return null;
        }
        getAbstractSession().getParent().getEventManager().addListener(listener);
        return listener;
    }

    /**
     * Return if stored procedures are supported for the database platform for the test database.
     */
    public static boolean supportsStoredProcedures(Session session) {
        DatabasePlatform platform = session.getPlatform();
        return platform.isOracle() || platform.isSybase() || platform.isMySQL() || platform.isSQLServer() || platform.isSymfoware();
    }

    /**
     * Force a garbage collection.
     */
    public void forceGC() {
        WeakReference ref = new WeakReference(new Object());
        for (int loops = 0; loops < 10; loops++) {
            //List junk = new ArrayList (10);
            for (int i = 0; i < 10; i++) {
                //junk.add(new java.math.BigDecimal(i));
            }

            // Force garbage collection.
            System.gc();
            System.runFinalization();
        }
        // Check if a garbage collect really occurred.
        if (ref.get() != null) {
            System.out.println("WARNING: gc did not occur");
        }
    }
}
