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

import org.eclipse.persistence.testing.framework.*;

/**
 * Custom WriteObjectTests that will allow the TypeTester object to pass through the calls to:
 * test(), setup(), &amp; verify(). This ius required so the tests can customize according to the platform.
 */
public class WriteTypeObjectTest extends WriteObjectTest {

    /** The following allows individual tests to be run with or without using native sql. */
    protected boolean useNativeSQL = false;
    protected boolean didUseNativeSQL = false;

    public WriteTypeObjectTest(TypeTester originalObject) {
        super(originalObject);
        // Need to set shouldMutate to false as the mutator method causes problems
        // with tests that pass in null values and field length tests.
        super.setTestShouldMutate(false);
    }

    @Override
    public String getName() {
        return "WriteTypeObjectTest(" + originalObject.getClass() + ")";
    }

    protected Object getObjectFromDatabase() {
        return this.objectFromDatabase;
    }

    @Override
    protected void setup() {
        if (shouldUseNativeSQL()) {
            if (!getSession().getLogin().shouldUseNativeSQL()) {
                setDidUseNativeSQL(true);
                getAbstractSession().getAccessor().disconnect(getAbstractSession());
                getSession().getLogin().setUsesNativeSQL(true);
                getAbstractSession().getAccessor().connect(getSession().getLogin(), getAbstractSession());
            }
        }
        ((TypeTester)this.originalObject).setup(getSession());
        super.setup();
    }

    protected void superTest() {
        super.test();
    }

    /**
     * Verify if the objects match completely through allowing the session to use the descriptors.
     * This will compare the objects and all of their privately owned parts.
     */
    protected void superVerify() throws TestErrorException, TestWarningException {
        super.verify();
    }

    @Override
    protected void test() {
        ((TypeTester)this.originalObject).test(this);
    }

    public String toString() {
        return originalObject.toString();
    }

    /**
     * Verify if the objects match completely through allowing the session to use the descriptors.
     * This will compare the objects and all of their privately owned parts.
     */
    @Override
    protected void verify() throws TestErrorException, TestWarningException {
        ((TypeTester)this.originalObject).verify(this);
    }

    /**
     * Was native sql used for this test only?
     */
    protected boolean didUseNativeSQL() {
        return didUseNativeSQL;
    }

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

        if (didUseNativeSQL()) {
            getAbstractSession().getAccessor().disconnect(getAbstractSession());
            getSession().getLogin().setUsesNativeSQL(false);
            getAbstractSession().getAccessor().connect(getSession().getLogin(), getAbstractSession());
        }
    }

    /**
     * Notify the test that the session's usesNativeSQL setting needs to be
     * reset after the test.
     */
    protected void setDidUseNativeSQL(boolean value) {
        didUseNativeSQL = value;
    }

    /**
     * Allows one to set usesNativeSQL to true on a test by test basis.
     */
    public void setUseNativeSQL(boolean value) {
        useNativeSQL = value;
    }

    public boolean shouldUseNativeSQL() {
        return useNativeSQL;
    }
}
