/*
 * 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.*;
import java.util.*;
import jakarta.persistence.*;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.sessions.server.*;

/**
 * <p>
 * <b>Purpose</b>: Allow for a test or set of tests to be executed and manage their execution and results.
 * <p>
 * <b>Responsibilities</b>:
 * <ul>
 * <li> Execute the test entity.
 * <li> Sets a flag to either log the results of test or not.
 * <li> Handles the exception returned by the test entity.
 * </ul>
 */
public class TestExecutor {

    /** It is a Stream where the test entity results are logged into */
    protected Writer log;
    /** This attribute is added to migrate tests to Ora*Tst */
    protected Writer regressionLog;

    /** Session used to run tests. */
    protected Session session;

    /** EntityManagerFactory used to run JPA tests. */
    protected EntityManagerFactory entityManagerFactory;

    /** Allows the original test session to be stored and repalced. */
    protected Session originalSession;

    /** A boolean, when set to true would start handling the exceptions thrown by TopLink
     * and would not when set to false. */
    protected boolean shouldHandleErrors;

    /** When set to true would log the results */
    protected boolean shouldLogResults;

    protected Hashtable loadedModels;

    /** Contains a collection of all the configured systems */
    protected Vector configuredSystems;

    /** This is used to stop execution thread */
    protected boolean shouldStopExecution;

    /** Used for test event progress notification */
    protected junit.framework.TestListener listener;

    /** Hold a default executor.  Used to cache the executor for tests run in JUnit. */
    protected static TestExecutor executor;

    /** Hold a default JUnit TestResult.  Used to cache the result for JUnit tests run by the executor. */
    protected static junit.framework.TestResult defaultJUnitTestResult;

    /** Hold JUnit TestResult but test.  Used to store the results for JUnit tests run by the executor. */
    protected static Map junitTestResults;

    /** This is used to get rid pf tests running on server(OC4J) */
    public boolean isServer = false;

    /** Allow only errors to be logged. */
    protected boolean shouldLogOnlyErrors = false;

    public static String CR = org.eclipse.persistence.internal.helper.Helper.cr();

    /**
     * Return a default executor.  Used as the executor for tests run in JUnit, or by themselves.
     */
    public static TestExecutor getDefaultExecutor() {
        if (executor == null) {
            TestExecutor testExecutor = new TestExecutor();
            testExecutor.setSession((new TestSystem()).login());
            // Ensure connect successful before setting executor.
            executor = testExecutor;
        }
        return executor;
    }

    /**
     * Return if only errors should be logged.
     */
    public boolean shouldLogOnlyErrors() {
        return shouldLogOnlyErrors;
    }

    /**
     * Set if only errors should be logged.
     */
    public void setShouldLogOnlyErrors(boolean shouldLogOnlyErrors) {
        this.shouldLogOnlyErrors = shouldLogOnlyErrors;
    }

    /**
     * Set the default executor.  Used as the executor for tests run in JUnit, or by themselves.
     */
    public static void setDefaultExecutor(TestExecutor theExecutor) {
        executor = theExecutor;
    }

    /**
     * Set the default JUnit TestResult.  Used to cache the result for JUnit tests run by the executor.
     */
    public static void setDefaultJUnitTestResult(junit.framework.TestResult theTestResult) {
        defaultJUnitTestResult = theTestResult;
    }

    /**
     * Return the default JUnit TestResult.  Used to cache the result for JUnit tests run by the executor.
     */
    public static junit.framework.TestResult getDefaultJUnitTestResult() {
        return defaultJUnitTestResult;
    }

    /**
     * Set the JUnit TestResults.  Used to store the result for JUnit tests run by the executor.
     */
    public static void setJUnitTestResults(Map results) {
        junitTestResults = results;
    }

    /**
     * Return the JUnit TestResults.  Used to store the result for JUnit tests run by the executor.
     */
    public static Map getJUnitTestResults() {
        if (junitTestResults == null) {
            junitTestResults = new HashMap();
        }
        return junitTestResults;
    }

    public TestExecutor() {
        this.log = new OutputStreamWriter(System.out);
        this.shouldLogResults = true;
        this.shouldHandleErrors = false;
        this.shouldStopExecution = false;
        this.configuredSystems = new Vector();
    }

    /**
     * INTERNAL:
     * Add persistent system to the executor configuration.
     */
    public void addConfigureSystem(TestSystem system) {
        if (!configuredSystemsContainsInstanceOf(system)) {
            getConfiguredSystems().addElement(system);
        }
    }

    /**
     * The loaded models hold all model in use to allow test case
     * The access other model to reuse their to setup.
     */
    public void addLoadedModels(Vector models) {
        for (Enumeration theModels = models.elements(); theModels.hasMoreElements();) {
            TestModel model = (TestModel)theModels.nextElement();
            getLoadedModels().put(model.getName(), model);
        }
    }

    /**
     * If the system is not already configured then configure it and store it in the executor.
     */
    public void configureSystem(TestSystem system) throws Exception {
        if (!configuredSystemsContainsInstanceOf(system)) {
            system.run(getSession());
            getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
            getConfiguredSystems().addElement(system);
        }
    }

    /**
     * Return true if the configuredSystems contains an instance of the class of the TestSystem parameter.
     */
    public boolean configuredSystemsContainsInstanceOf(TestSystem system) {
        for (Enumeration configuredSystemsEnum = getConfiguredSystems().elements();
                 configuredSystemsEnum.hasMoreElements();) {
            if (configuredSystemsEnum.nextElement().getClass().equals(system.getClass())) {
                return true;
            }
        }
        return false;
    }

    /**
     * PUBLIC:
     * The executor stops handling errors and throws them to the user. This is mainly
     * for testing purpose to actully know the place of problem.
     */
    public void doNotHandleErrors() {
        setShouldHandleErrors(false);
    }

    /**
     * PUBLIC:
     * The executor would stop logging error to the log stream.
     */
    public void doNotLogResults() {
        setShouldLogResults(false);
    }

    public void doNotStopExecution() {
        setShouldStopExecution(false);
    }

    /**
     * PUBLIC:
     * To execute any test entity.
     */
    public void execute(junit.framework.Test test) throws Throwable {
        if (shouldStopExecution()) {
            return;
        }

        try {
            getSession().logMessage("Begin " + test);
            if (getListener() != null) {
                getListener().startTest(test);
            }

            // If the suite was run through JUnit, or is a Junit suite,
            // run through the result, otherwise through the executor.
            if ((getDefaultJUnitTestResult() != null) || (!(test instanceof TestEntity))) {
                junit.framework.TestResult result = getDefaultJUnitTestResult();
                if (getDefaultJUnitTestResult() == null) {
                    result = new junit.framework.TestResult();
                    result.addListener(getListener());
                }
                getJUnitTestResults().put(test, result);
                test.run(result);
            } else {
                ((TestEntity)test).execute(this);
            }
            if (getListener() != null) {
                getListener().endTest(test);
            }
            getSession().logMessage("Finished " + test);
            if (getAbstractSession().isInTransaction()) {
                throw new TestProblemException(test + " is a faulty test, transaction was left open and must always be closed.");
            }
        } catch (Throwable exception) {
            // Always catch warnings, and handle errors if shouldHandleErrors set.
            if ((!(exception instanceof TestWarningException)) && (!shouldHandleErrors())) {
                throw exception;
            }
            if (getListener() != null) {
                getListener().endTest(test);
            }
            getSession().logMessage("Failed " + test);
            System.err.println(test + " FAILED");
        }
    }

    /**
     * Forced system to be configured even if it is already configured.
     */
    public void forceConfigureSystem(TestSystem system) throws Exception {
        removeConfigureSystem(system);
        system.run(getSession());
        addConfigureSystem(system);
    }

    /**
     * Return all the configured systems.
     */
    public Vector getConfiguredSystems() {
        return configuredSystems;
    }

    /**
     * Used for test event progress notifiaction.
     */
    public junit.framework.TestListener getListener() {
        return listener;
    }

    /**
     * Return the model by name.
     * If missing null is returned.
     */
    public TestModel getLoadedModel(String modelsName) {
        return (TestModel)getLoadedModels().get(modelsName);
    }

    /**
     * The loaded models hold all model in use to allow test case
     * The access other model to reuse their to setup.
     */
    public Hashtable getLoadedModels() {
        return loadedModels;
    }

    /**
     * Return the log stream to print the results on. Default is console.
     * This method is added to migrate to Ora*Tst
     */
    public Writer getRegressionLog() {
        return regressionLog;
    }

    /**
     * Return the log stream to print the results on. Default is console.
     */
    public Writer getLog() {
        if (getSession() == null) {
            return log;
        }
        return getSession().getLog();
    }

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

    /**
     * Return the executor entity manager factory.
     * This lazy initializes from the "performance" persistent unit using the default provider,
     * and configures the TopLink properties to connect to the executor's session's login.
     */
    public EntityManagerFactory getEntityManagerFactory() {
        if (entityManagerFactory == null) {
            Map properties = getEntityManagerProperties();
            entityManagerFactory = Persistence.createEntityManagerFactory("performance", properties);
        }
        return entityManagerFactory;
    }

    /**
     * Return the executor entity manager factory.
     * This lazy initializes from the "performance" persistent unit using the default provider,
     * and configures the TopLink properties to connect to the executor's session's login.
     */
    public Map getEntityManagerProperties() {
        Map properties = new HashMap();
        properties.put(PersistenceUnitProperties.JDBC_DRIVER, getSession().getLogin().getDriverClassName());
        properties.put(PersistenceUnitProperties.JDBC_URL, getSession().getLogin().getConnectionString());
        properties.put(PersistenceUnitProperties.JDBC_USER, getSession().getLogin().getUserName());
        properties.put(PersistenceUnitProperties.JDBC_PASSWORD, getSession().getLogin().getPassword());
        properties.put(PersistenceUnitProperties.LOGGING_LEVEL, getSession().getSessionLog().getLevelString());
        return properties;
    }

    /**
     * Set the executor entity manager factory.
     */
    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

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

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

    /**
     * Return the session.
     */
    public Session getSession() {
        return session;
    }

    /**
     * Return the original session.
     */
    public Session getOriginalSession() {
        return originalSession;
    }

    /**
     * Set the original session.
     */
    public void setOriginalSession(Session originalSession) {
        this.originalSession = originalSession;
    }

    /**
     * Swap the current session with the new session.
     * This allows a test or model to customize the session it uses.
     */
    public void swapSession(Session newSession) {
        setOriginalSession(getSession());
        setSession(newSession);
    }

    /**
     * Swap the current session with a new database session with the same login,
     * but no descriptors.
     */
    public void swapCleanDatabaseSession() {
        DatabaseSession session = new Project(getSession().getLogin()).createDatabaseSession();
        session.setSessionLog(getSession().getSessionLog());
        session.login();
        swapSession(session);
    }

    /**
     * Swap the current session with the new server session.
     */
    public void swapServerSession() {
        Server session = getSession().getProject().createServerSession();
        session.setSessionLog(getSession().getSessionLog());
        session.login();
        swapSession(session);
    }

    /**
     * Swap the current session with the new session.
     * This allows a test or model to customize the session it uses.
     */
    public void resetSession() {
        if(getOriginalSession() != null) {
            if(getDatabaseSession().isConnected()) {
                getDatabaseSession().logout();
            }
            setSession(getOriginalSession());
            setOriginalSession(null);
        }
    }

    /**
     * PUBLIC:
     * Starts handling errors. Even if some error is raised Executor just
     * catches it and goes on to execute the next test.
     */
    public void handleErrors() {
        setShouldHandleErrors(true);
    }

    public void initializeConfiguredSystems() {
        setConfiguredSystems(new Vector());
    }

    /**
     * This logs out from session.
     */
    protected void logout() {
        if (session != null) {
            ((DatabaseSession)session).logout();
        }
    }

    /**
     * Logs the result for the given test entity if logResults is true.
     * This method is added to migrate tests to Ora*Tst
     */
    public void logRegressionResultForTestEntity(junit.framework.Test test) {
        logResultForTestEntity(test, true);
    }

    /**
     * Logs the result for the given test entity if logResults is true.
     */
    public void logResultForTestEntity(junit.framework.Test test) {
        logResultForTestEntity(test, false);
    }

    /**
     * Logs the result for the given test entity if logResults is true.
     */
    public void logResultForTestEntity(junit.framework.Test test, boolean regression) {
        Writer log = getLog();
        if (regression) {
            log = getRegressionLog();
        }
        if (shouldStopExecution()) {
            try {
                log.write("!!! THE TEST EXECUTION WAS INTERRUPTED !!!");
                log.flush();
            } catch (IOException e) {
            }
        }

        if (shouldLogResults()) {
            if (test instanceof TestEntity) {
                TestEntity testEntity = (TestEntity)test;
                testEntity.resetNestedCounter();
                if (regression) {
                    testEntity.logRegressionResult(log);
                } else {
                    testEntity.logResult(log, shouldLogOnlyErrors());
                }
                testEntity.resetNestedCounter();
            } else {
                logJUnitResult(test, log, "");
            }
        }
        try {
            log.flush();
        } catch (IOException e) {
        }
    }

    /**
     * Log any JUnit results if present.
     */
    public static void logJUnitResult(junit.framework.Test test, Writer log, String indent) {
        try {
            log.write(CR);
            log.write(CR);
            log.write(indent + "TEST MODEL NAME: (JUnit test): " + test);
            log.write(CR);
            junit.framework.TestResult result = (junit.framework.TestResult) TestExecutor.getJUnitTestResults().get(test);
            if (result == null) {
                log.write(indent + "## SETUP FAILURE ## (no tests run)");
                log.write(CR);
                log.flush();
                return;
            }
            if ((result.failureCount() > 0) || (result.errorCount() > 0)) {
                log.write(indent + "###ERRORS###" + CR);
            }
            log.write(CR);
            log.write(indent + "Errors: (failures): " + result.failureCount());
            log.write(CR);
            log.write(indent + "Fatal Errors: (errors): " + result.errorCount());
            log.write(CR);
            log.write(indent + "Passed: " + (result.runCount() - result.errorCount() - result.failureCount()));
            log.write(CR);
            log.write(indent + "Total Tests: " + result.runCount());
            log.write(CR);
            if (result.failureCount() > 0) {
                log.write(CR);
                log.write(indent + "Failures:");
                log.write(CR);
                for (Enumeration failures = result.failures(); failures.hasMoreElements();) {
                    junit.framework.TestFailure failure = (junit.framework.TestFailure)failures.nextElement();
                    String testString = failure.failedTest().toString();
                    int startIndex = testString.indexOf("(");
                    if (startIndex != -1) {
                        log.write(indent + "TEST SUITE NAME: " + testString.substring(startIndex + 1, testString.length() - 1));
                        log.write(CR);
                    }
                    log.write(indent + "TEST NAME: " + testString);
                    log.write(CR);
                    log.write(indent + "##FAILURE##" + CR);
                    log.write(indent + "RESULT:      Error (failure)");
                    log.write(CR);
                    log.write(indent + failure.trace());
                    log.write(CR);
                }
            }
            if (result.errorCount() > 0) {
                log.write(CR);
                log.write(indent + "Errors:");
                log.write(CR);
                for (Enumeration errors = result.errors(); errors.hasMoreElements();) {
                    junit.framework.TestFailure error = (junit.framework.TestFailure)errors.nextElement();
                    String testString = error.failedTest().toString();
                    int startIndex = testString.indexOf("(");
                    if (startIndex != -1) {
                        log.write(indent + "TEST SUITE NAME: " + testString.substring(startIndex + 1, testString.length() - 1));
                        log.write(CR);
                    }
                    log.write(indent + "TEST NAME: " + testString);
                    log.write(CR);
                    log.write(indent + "##FAILURE##" + CR);
                    log.write(indent + "RESULT:      FatalError (error)");
                    log.write(CR);
                    log.write(indent + error.trace());
                    log.write(CR);
                }
            }
            log.write(CR);
            log.flush();
        } catch (IOException exception) {
        }
    }

    /**
     * Log the results to the log stream.
     */
    public void logResults() {
        setShouldLogResults(true);
    }

    /**
     * Public:
     * This method is used if we use dos promt to run our test cases.
     */
    public static void main(String[] arguments) {
        try {
            TestExecutor executor = new TestExecutor();

            //        executor.handleErrors();
            //        executor.doNotLogResults();
            executor.execute((TestEntity)Class.forName(arguments[0]).getConstructor().newInstance());
        } catch (Throwable exception) {
            System.out.println(exception.toString());
        }
    }

    public void removeConfigureSystem(TestSystem system) {
        removeFromConfiguredSystemsInstanceOf(system);
    }

    /**
     * If an instance of the same class as the parameter exists in the Vector of configuredSystems
     * then remove it.
     */
    public void removeFromConfiguredSystemsInstanceOf(TestSystem system) {
        // find and record the systems to remove
        Vector systemsToRemove = new Vector();
        for (Enumeration systemEnum = getConfiguredSystems().elements();
                 systemEnum.hasMoreElements();) {
            TestSystem aSystem = (TestSystem)systemEnum.nextElement();
            if (aSystem.getClass().equals(system.getClass())) {
                systemsToRemove.addElement(aSystem);
            }
        }

        // Do the removing
        for (Enumeration systemsToRemoveEnum = systemsToRemove.elements();
                 systemsToRemoveEnum.hasMoreElements();) {
            getConfiguredSystems().removeElement(systemsToRemoveEnum.nextElement());
        }
    }

    /**
     * The loaded models hold all model in use to allow test case
     * to access other model to reuse their to setup.
     */
    public void resetLoadedModels() {
        setLoadedModels(new Hashtable());
    }

    /**
     * PUBLIC:
     * This method executes the test entity. This method sets the session by using test
     * entity default login and once the execution is over it explicitily logs out.
     */
    public void runTest(junit.framework.Test test) throws Throwable {
        boolean hasSession = true;

        setShouldStopExecution(false);
        if ((getSession() == null) && (test instanceof TestEntity)) {
            TestEntity testEntity = (TestEntity)test;
            hasSession = false;
            if (shouldHandleErrors()) {
                try {
                    setSession(testEntity.defaultLogin());
                } catch (Exception exception) {
                    logout();
                    return;
                }
            } else {
                setSession(testEntity.defaultLogin());
            }
        }

        try {
            execute(test);
            //This line is added to migrate tests to Ora*Tst
            if (getRegressionLog() != null) {
                logRegressionResultForTestEntity(test);
            }
            logResultForTestEntity(test);
        } finally {
            if (!hasSession) {
                logout();
            }
        }
    }

    /**
     * Set configured systems.
     */
    public void setConfiguredSystems(Vector configuredSystems) {
        this.configuredSystems = configuredSystems;
    }

    /**
     * Used for test event progress notification.
     */
    public void setListener(junit.framework.TestListener listener) {
        this.listener = listener;
    }

    /**
     * The loaded models hold all model in use to allow test case
     * The access other model to reuse their to setup.
     */
    protected void setLoadedModels(Hashtable loadedModels) {
        this.loadedModels = loadedModels;
    }

    /**
     * PUBLIC:
     * Set the log stream to which test results should be logged on.
     * This method is added to migrate to Ora*Tst
     */
    public void setRegressionLog(Writer writer) {
        this.regressionLog = writer;
    }

    /**
     * PUBLIC:
     * Set the log stream to which test results should be logged on.
     */
    public void setLog(Writer writer) {
        this.log = writer;
    }

    /**
     * PUBLIC:
     * Set the session
     */
    public void setSession(Session theSession) {
        // Don't allow bad tests to set session to null.
        if (theSession == null) {
            return;
        }
        session = theSession;
    }

    public void setShouldHandleErrors(boolean aBoolean) {
        shouldHandleErrors = aBoolean;
    }

    public void setShouldLogResults(boolean aBoolean) {
        shouldLogResults = aBoolean;
    }

    public void setShouldStopExecution(boolean aBoolean) {
        shouldStopExecution = aBoolean;
    }

    /**
     * Returns if errors are to be handled or not.
     */
    public boolean shouldHandleErrors() {
        return shouldHandleErrors;
    }

    /**
     * Returns if results should be logged or not.
     */
    public boolean shouldLogResults() {
        return shouldLogResults;
    }

    /**
     * Returns if test entities should be execute or not.
     */
    public boolean shouldStopExecution() {
        return shouldStopExecution;
    }

    public void stopExecution() {
        setShouldStopExecution(true);
    }
}
