/*
 * Copyright (c) 1998, 2020 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]).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);
    }
}
