/*******************************************************************************
 * Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.testing.framework;

import java.io.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.Login;
import org.eclipse.persistence.testing.framework.TestExecutor;
import org.eclipse.persistence.sessions.factories.SessionManager;

/**
 * <p><b>Purpose</b>: Test model is a collection of test suites and/or sub test models. When a
 * test model is executed all the test suites and models registered with it are
 * executed one by one.
 */
public class TestModel extends TestCollection {

    /** Configurations that must be set before this model is run */
    private Vector requiredSystems;

    /** The model will force these Configurations to be set even if they are set before */
    private Vector forcedRequiredSystems;

    /** Used to store tests added when the model is built. */
    private Vector originalTests;

    /** Keep track of setup state. */
    private boolean isSetup;

    /** Ensure the login and log are not corrupted if the session is changed. */
    private Login login;
    private SessionLog sessionLog;

    /**
     * Flag used to determine if tables should be recreated/populated before each test model.
     * true means tests will take longer to run, but run more consistently as bad tests will not effect other models.
     * Uses system property "org.eclipse.persistence.testing.reset-system".
     */
    private static Boolean shouldResetSystemAfterEachTestModel;

    /**
     * Flag used to determine if tables should be recreated/populated before each test model.
     * true means tests will take longer to run, but run more consistently as bad tests will not effect other models.
     * Uses system property "org.eclipse.persistence.testing.reset-system".
     */
    public static boolean shouldResetSystemAfterEachTestModel() {
        if (shouldResetSystemAfterEachTestModel == null) {
            String systemProperty = System.getProperty("org.eclipse.persistence.testing.reset-system");
            if (systemProperty == null) {
                shouldResetSystemAfterEachTestModel = Boolean.TRUE;
            } else {
                if (systemProperty.equals("false")) {
                    shouldResetSystemAfterEachTestModel = Boolean.FALSE;
                } else {
                    shouldResetSystemAfterEachTestModel = Boolean.TRUE;
                }
            }
        }
        return shouldResetSystemAfterEachTestModel.booleanValue();
    }

    /**
     * Flag used to determine if tables should be recreated/populated before each test model.
     * true means tests will take longer to run, but run more consistently as bad tests will not effect other models.
     * Uses system property "org.eclipse.persistence.testing.reset-system".
     */
    public static void setShouldResetSystemAfterEachTestModel(boolean value) {
        if (value) {
            shouldResetSystemAfterEachTestModel = Boolean.TRUE;
        } else {
            shouldResetSystemAfterEachTestModel = Boolean.FALSE;
        }
    }

    public TestModel() {
        this.requiredSystems = new Vector();
        this.forcedRequiredSystems = new Vector();
        this.isSetup = false;
        this.originalTests = new Vector();
    }

    /**
     * The system add will be forced to be initialized again even if it is already configured.
     * Basically this means that required system will recreate new database.
     */
    public final void addForcedRequiredSystem(TestSystem requiredSystem) {
        getForcedRequiredSystems().addElement(requiredSystem);
    }

    /**
     * The system add will be forced to be initialized again even if it is already configured.
     * Basically this means that required system will recreate new database. This method should always
     * be overwritten in the subclasses if the model needs some persistence system to be already configured
     * before it is run.
     */
    public void addForcedRequiredSystems() {
    }

    /**
     * The system add will be configured if it has not been already configured.
     * Basically this means that required system will recreate new database.
     */
    public final void addRequiredSystem(TestSystem requiredSystem) {
        getRequiredSystems().addElement(requiredSystem);
    }

    /**
     * The system add will be configured if it has not been already configured.
     * Basically this means that required system will recreate new database.
     * This method should always be overwritten in the subclasses if the model
     * needs some persistence system to be already configured before it is run.
     */
    public void addRequiredSystems() {
    }

    /**
     * The subclasses must overwrite this method. To add tests to the model.
     * It could be collection of test suites or test models themselves.
     */
    public void addTests() {
    }

    /**
     * The subclasses must overwrite this method. To add tests to the model.
     * It could be collection of test suites or test models themselves.
     */
    public void addSRGTests() {
    }

    /**
     * Build the required systems, but ensure that the variable is not modified.
     */
    public Vector buildForcedRequiredSystems() {
        Vector constructedSystems = (Vector)getForcedRequiredSystems().clone();
        addForcedRequiredSystems();
        Vector allSystems = getForcedRequiredSystems();
        setForcedRequiredSystems(constructedSystems);
        return allSystems;
    }

    /**
     * Build the required systems, but ensure that the variable is not modified.
     */
    public Vector buildRequiredSystems() {
        Vector constructedSystems = (Vector)getRequiredSystems().clone();
        addRequiredSystems();
        Vector allSystems = getRequiredSystems();
        setRequiredSystems(constructedSystems);
        return allSystems;
    }

    /**
     * Goes through each systems and configures them.
     */
    private void configure() throws Exception {
        Vector systems = buildRequiredSystems();

        for (Enumeration enumtr = systems.elements(); enumtr.hasMoreElements();) {
            TestSystem system = (TestSystem)enumtr.nextElement();

            // To improve test consistency always force systems to be reset.
            if (shouldResetSystemAfterEachTestModel()) {
                getExecutor().forceConfigureSystem(system);
            } else {
                getExecutor().configureSystem(system);
            }
        }

        systems = buildForcedRequiredSystems();

        for (Enumeration enumtr = systems.elements(); enumtr.hasMoreElements();) {
            TestSystem system = (TestSystem)enumtr.nextElement();
            getExecutor().forceConfigureSystem(system);
        }
    }

    /**
     * Executes all the test entities in the collection.
     */
    public void execute(TestExecutor executor) throws Throwable {
        setSummary(new TestResultsSummary(this));
        setExecutor(executor);
        long startTime = System.currentTimeMillis();
        try {
            setupEntity();
            setFinishedTests(new Vector());
            try {
                for (Enumeration tests = getTests().elements(); tests.hasMoreElements();) {
                    junit.framework.Test test = (junit.framework.Test)tests.nextElement();
                    if ((TestExecutor.getDefaultJUnitTestResult() != null) && TestExecutor.getDefaultJUnitTestResult().shouldStop()) {
                            break;
                    }
                    executor.execute(test);
                    getFinishedTests().addElement(test);
                }
            } catch (Throwable exception) {
                try {
                    resetEntity();
                } catch (Throwable ignore) {
                }
                throw exception;
            }
            resetEntity();
        } finally {
            long endTime = System.currentTimeMillis();
            getSummary().setTotalTime(endTime - startTime);
        }
    }

    /**
     * Return all the required systems that need to be configured even if they are already configured.
     */
    public Vector getForcedRequiredSystems() {
        return forcedRequiredSystems;
    }

    /**
     * Return test that existed before setup.
     */
    protected Vector getOriginalTests() {
        return originalTests;
    }

    /**
     * Return all the required systems that need to be configured if they are not already configured.
     */
    public Vector getRequiredSystems() {
        return requiredSystems;
    }

    public boolean isSetup() {
        return isSetup;
    }

    /**
     * Format the test output on the print stream.
     */
    protected void logFootNote(Writer log) {
        try {
            log.write(org.eclipse.persistence.internal.helper.Helper.cr() + getIndentationString() + "RESULTS OF TEST MODEL: " + getName() + org.eclipse.persistence.internal.helper.Helper.cr());
        } catch (IOException exception) {
        }
    }

    /**
     * Format the test output on the print stream.
     * This method is added to migrate tests to Ora*Tst
     */
    protected void logRegressionHeadNote(Writer log) {
        try {
            log.write(org.eclipse.persistence.internal.helper.Helper.cr() + getIndentationString() + "TEST MODEL NAME: " + getName() + org.eclipse.persistence.internal.helper.Helper.cr());
            log.write(getIndentationString() + "MODEL DESCRIPTION: " + getDescription() + org.eclipse.persistence.internal.helper.Helper.cr());
        } catch (IOException exception) {
        }
    }

    /**
     * Format the test output on the print stream.
     */
    protected void logHeadNote(Writer log) {
        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 MODEL NAME: " + getName() + org.eclipse.persistence.internal.helper.Helper.cr());
            log.write(getIndentationString() + "MODEL DESCRIPTION: " + getDescription() + org.eclipse.persistence.internal.helper.Helper.cr());
        } catch (IOException exception) {
        }
    }

    /**
     * This is a optional method and it should be overridden if their is something
     * that test collection should perform after running itself.
     */
    public void reset() {
        return;
    }

    /**
     * If setupEntity has been called then this must be called to reset the model again.
     */
    public void resetEntity() {
        if (isSetup()) {
            setTests(getOriginalTests());
            setIsSetup(false);
        }
        if(this.getSummary().didSetupWarn()) {
            return;
        }
        reset();
        // To improve test consistency cleanup the session and executor better.
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
        if (shouldResetSystemAfterEachTestModel()) {            
            getExecutor().setConfiguredSystems(new Vector());

            // Logout and clean/reset the session in case test model failed ungracefully.
            if (getSession().isDatabaseSession()) {
                try {
                    getDatabaseSession().logout();
                } catch (Exception ignore) {
                }
            }
            if (this.login == null) {
                this.login = getSession().getDatasourceLogin();
                this.sessionLog = getSession().getSessionLog();
            }
            // Check if login or log were corrupted.
            if (this.login.getClass() != getSession().getDatasourceLogin().getClass()) {
                System.out.println("Login changed by test model:" + this);
            }
            if (this.sessionLog.getLevel() != getSession().getSessionLog().getLevel()) {
                System.out.println("Log level changed by test model:" + this);
            }
            if (this.login instanceof DatabaseLogin) {
                DatabaseLogin login = (DatabaseLogin)this.login;
                if (login.shouldBindAllParameters() != getSession().getLogin().shouldBindAllParameters()) {
                    System.out.println("Binding changed by test model:" + this);
                }
                if (login.shouldCacheAllStatements() != getSession().getLogin().shouldCacheAllStatements()) {
                    System.out.println("Statement caching changed by test model:" + this);
                }
                if (login.shouldUseBatchWriting() != getSession().getLogin().shouldUseBatchWriting()) {
                    System.out.println("Batch writing changed by test model:" + this);
                }
                if (login.shouldUseJDBCBatchWriting() != getSession().getLogin().shouldUseJDBCBatchWriting()) {
                    System.out.println("JDBC batch writing changed by test model:" + this);
                }
                if (login.shouldUseNativeSQL() != getSession().getLogin().shouldUseNativeSQL()) {
                    System.out.println("Native SQL changed by test model:" + this);
                }
                if (login.getTableQualifier() != getSession().getLogin().getTableQualifier()) {
                    System.out.println("Table qualifier changed by test model:" + this);
                }
            }
            DatabaseSession session = new Project(this.login).createDatabaseSession();
            session.setSessionLog(this.sessionLog);
            getExecutor().setSession(session);
            // Check if default conversion manager was corrupted.
            if (!ConversionManager.getDefaultManager().shouldUseClassLoaderFromCurrentThread()) {
                System.out.println("ConversionManager corrupted by test model:" + this);
            }
            ConversionManager.setDefaultManager(null);
            getSession().getDatasourceLogin().getDatasourcePlatform().setConversionManager(null);
            SessionManager.getManager().setSessions(new ConcurrentHashMap<String, Session>());
            getDatabaseSession().login();
        }
        setIsSetup(false);
    }

    /**
     * Set all the required systems that need to be configured even if they are already configured.
     */
    public void setForcedRequiredSystems(Vector systems) {
        this.forcedRequiredSystems = systems;
    }

    protected void setIsSetup(boolean isSetup) {
        this.isSetup = isSetup;
    }

    /**
     * Set the test that existed before setup.
     */
    protected void setOriginalTests(Vector originalTests) {
        this.originalTests = originalTests;
    }

    /**
     * Set all the required sytems that need to be configured if they are not already configured.
     */
    public void setRequiredSystems(Vector systems) {
        this.requiredSystems = systems;
    }

    /**
     * This is a optional method and it should be overridden if their is something
     * that test collection should perform before running itself.
     */
    public void setup() {
        return;
    }

    /**
     * To set up the model also look at resetEntity
     */
    public void setupEntity() throws Throwable {
        if (isSetup()) {
            return;
        }
        if (getSession() != null) {
            // Force field names to uppercase for postgres.
            if (getSession().getDatasourcePlatform().isPostgreSQL()) {
                getSession().getPlatform().setShouldForceFieldNamesToUpperCase(true);
            }
            this.login = getSession().getDatasourceLogin().clone();
            this.sessionLog = (SessionLog)getSession().getSessionLog().clone();
        }
        try {
            setOriginalTests((Vector)getTests().clone());
            configure();
            setup();
            if (isSRG) {
                addSRGTests();
            } else {
                addTests();
            }

            // Check for faulty models leaving transaction open.
            if ((getAbstractSession() != null) && getAbstractSession().isInTransaction()) {
                try {
                    int count = 0;
                    while (getAbstractSession().isInTransaction() && (count < 10)) {
                        getAbstractSession().rollbackTransaction();
                        count++;
                    }
                } catch (Throwable ignore) {
                }
                TestProblemException exception = new TestProblemException(this + " is a faulty test, transaction was left open and must always be closed.");
                throw exception;
            }
        } catch (Throwable exception) {
            getSummary().setSetupException(exception);

            try {
                resetEntity();
            } catch (Throwable resetException) {
            }

            throw exception;
        }

        setIsSetup(true);
    }

    /**
     * Returns the number of tests in this suite.
     * If not setup, return the finished tests.
     */
    public int testCount() {
        if (isSetup() || (!getTests().isEmpty())) {
            return super.testCount();
        }
        return getFinishedTests().size();
    }

    /**
     * Returns the tests as an enumeration.
     * If not setup, return the finished tests.
     */
    public Enumeration tests() {
        if (isSetup() || (!getTests().isEmpty())) {
            return super.tests();
        }
        return getFinishedTests().elements();
    }

    /**
     * Returns the test at the given index.
     * If not setup, return the finished tests.
     */
    public junit.framework.Test testAt(int index) {
        if (isSetup() || (!getTests().isEmpty())) {
            return super.testAt(index);
        }
        return (junit.framework.Test)getFinishedTests().elementAt(index);
    }
}
