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

import java.util.Vector;

import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.testing.tests.flashback.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.history.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.tests.employee.EmployeeBasicTestModel;

public class HistoryTestModel extends FlashbackTestModel {

    int mode;
    public static int BASIC = 0;
    public static int PROJECT_XML = 1;
    public static int PROJECT_CLASS_GENERATED = 2;

    public HistoryTestModel(int mode) {
        setDescription("Tests the new flashback query tests, but using a Historical Schema.");
        this.mode = mode;
        if (mode == BASIC) {
            setName("HistoryTestModel");
        } else if (mode == PROJECT_XML) {
            setName("ProjectXMLHistoryTestModel");
        } else if (mode == PROJECT_CLASS_GENERATED) {
            setName("ProjectClassGeneratedHistoryTestModel.");
        }
    }

    @Override
    public void addTests() {
        super.addTests();

        addTest(new RollbackObjectsTest(Employee.class, getAsOfClause()));
        addTest(EmployeeBasicTestModel.getReadObjectTestSuite());
        addTest(EmployeeBasicTestModel.getReadAllTestSuite());
        addTest(EmployeeBasicTestModel.getInsertObjectTestSuite());
        buildUpdateObjectTestSuite();
        addTest(EmployeeBasicTestModel.getDeleteObjectTestSuite());
        addTest(new IsolatedSessionHistoricalTest(getAsOfClause()));
        addTest(new InsertWithHistoryPolicyTest()); // Bug 319276
    }

    private void configure() throws Exception {

        TestSystem system = new HistoricalEmployeeSystem(mode);

        system.run(getSession());
        buildAsOfClause();
        Thread.sleep(1000);
        depopulate();
        return;
    }

    @Override
    public void buildAsOfClause() {
        //DatabasePlatform platform = (DatabasePlatform)getSession().getPlatform();
        //ValueReadQuery timestampQuery = platform.getTimestampQuery();
        //asOfClause = new AsOfClause(getSession().executeQuery(timestampQuery));
        asOfClause = new AsOfClause(new java.sql.Timestamp(System.currentTimeMillis()));
    }

    /**
     * Assume setup() is called prior to addTests.  This seems bizarre
     * but is the way it works.
     */
    @Override
    public void setup() {
        // Must do configuration here...
        if (getTimestamp() != null) {
            return;
        }
        try {
            configure();
        } catch (EclipseLinkException te) {
            throw te;
        } catch (Exception ignore) {
            ignore.printStackTrace();
        }
    }

    protected void buildUpdateObjectTestSuite() {
        // Wrapper test throws a warning
        // in case the wrapped test throws a certain exception.
        class WrappedWriteObjectTest extends TestWrapper {
            public WrappedWriteObjectTest(TestCase test) {
                super(test);
            }
            @Override
            protected void test() throws Throwable {
                try {
                    super.test();
                } catch (DatabaseException databaseException) {
                    Throwable internalException = databaseException.getInternalException();
                    if(getSession().getPlatform().isMySQL()) {
                        if(internalException.getClass().getName().contains("MySQLIntegrityConstraintViolationException")) {
                            // two objects created / updated during the same second will have the same date/time representation
                            // in MySQL database column because on MySQL microseconds cannot be stored into a column of any temporal data type.
                            throw new TestWarningException("on MySQL microseconds cannot be stored into a column of any temporal data type, therefore the following exception occurred: ", internalException);
                        }
                    }
                    throw databaseException;
                }
            }
        }

        TestSuite testSuite = EmployeeBasicTestModel.getUpdateObjectTestSuite();
        if(getSession().getPlatform().isMySQL()) {
            TestSuite newTestSuite = new TestSuite();
            Vector tests = testSuite.getTests();
            for(int i=0; i<tests.size(); i++) {
                TestCase test = (TestCase)tests.elementAt(i);
                // Bug 210270: HistorySession causing unique constraint violation on MySQL.
                // To avoid test failure due to this bug,
                // wrap a test prone to MySQLIntegrityConstraintViolationException
                // in a wrapper that throws a warning in case this exception occur.
                test = new WrappedWriteObjectTest(test);
                newTestSuite.addTest(test);
            }
            testSuite = newTestSuite;
        }
        addTest(testSuite);
    }

}
