/*
 * 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 org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sessions.server.ClientSession;
import org.eclipse.persistence.descriptors.*;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.mappings.foundation.*;

import java.util.Enumeration;
import java.util.Vector;

/**
 * <p>
 * <b>Purpose</b>: Define a generic test for writing an object to the database.
 * Should originalObject contain no changes to the original object from the
 * database (a TRIVIAL UPDATE), find and mutate a direct to field mapping before
 * writing the object to the database.  If originalObject is different from but
 * has the same primary key as an object on the database, do not mutate the
 * object as it has already been changed (a NON-TRIVIAL UPDATE).
 * <p>
 * <b>Responsibilities</b>:
 * <ul>
 * <li> Be independent of the class being tested.
 * <li> Attempt to mutate a Direct to Field mapping if instructed to do so.
 * <li> Execute the insert object query and verify no errors occurred.
 * <li> Verify the object written matches the object that was written.
 * </ul>
 */
public class WriteObjectTest extends TransactionalTestCase {

    /** Query to read the original object from the database */
    protected ReadObjectQuery query;

    /** The original object that is set thru example methods from the model */
    protected Object originalObject;

    /** The originalObject is read from the database and stored here */
    protected Object objectToBeWritten;

    /** The object from the database is read in verify to compare against the
    * objectToBeWritten.
    */
    protected Object objectFromDatabase;

    /** The following allows individual tests to be run with or
     * without bind all parameters on. */
    protected Boolean bindAllParameters = null;
    protected Boolean bindAllParametersOriginal = null;

    /** An option to test non-trivial updates. */
    protected boolean makesTrivialUpdate = true;

    /** This determines whether the test should attempt to mutate the object.
     * This defaults to true.  It can be set to false where changing the object
     * will cause failures.
     */
    protected boolean testShouldMutate = true;

    public WriteObjectTest() {
        setDescription("The test writing of the intended object from the "+
            "database and checks if it was inserted properly");
    }

    public WriteObjectTest(Object originalObject) {
        this.originalObject = originalObject;
        setName(getName() + "(" + originalObject.getClass() + ")");
        setDescription(
            "The test writing of the intended object, '"+originalObject
            +"', from the database and checks if it was inserted properly");
    }

    public Object getOriginalObject() {
        return originalObject;
    }

    /**
     * A method that takes an object and attempts to find a direct to field
     * mapping that can be mutated.  The value of the mapping is changed by
     * appending a mutation string to the existing value in the mapping.
     * Should no suitable mapping be found, the method simply returns the
     * object passed in.
     * This covers test case bug 2773036
     */
    public Object findAndMutateDirectToFieldMappingInObject(Object objectToBeMutated, boolean isInUOW) {
        DatabaseMapping dbMapping = null;
        DatabaseMapping mutatableMapping = null;

        String mutationString = "M"; // The string to append

        /**
         * Here the class of the object passed is used to get the corresponding
         * descriptor, which is then used to find the mappings and determine if
         * one exists that can be mutated
         */
        Class<? extends Object> objectClass = objectToBeMutated.getClass();
        ClassDescriptor descriptor = getSession().getProject().getClassDescriptor(objectClass);
        Vector<DatabaseMapping> mappings = descriptor.getMappings();

        if (isInUOW) {
            mutationString += "U";
        }

        Enumeration<DatabaseMapping> en = mappings.elements();

        /**
         * Parse the mappings for the object's descriptor to find a suitable
         * mapping that can be mutated.  The mapping must meet the conditions:
         * Not a primary key mapping
         * Must be direct to field
         * Must be a string field
         * Must not have a converter (i.e. Male--{@literal >}M, Female--{@literal >}F, Unknown--{@literal >}U)
         * The loop exits once an appropriate mapping is found or the list of
         * mappings has been fully parsed (whichever occurs first)
         */
        while (en.hasMoreElements ()) {
            dbMapping = en.nextElement();

            if (!dbMapping.isPrimaryKeyMapping()
                    && dbMapping.isDirectToFieldMapping()
                    &&!((AbstractDirectMapping) dbMapping).hasConverter()
                    && (dbMapping.getAttributeAccessor().getAttributeClass())
                        .getName().indexOf("String") != -1) {
                mutatableMapping = dbMapping;
                break;
            }
        }

        /**
         * If a mapping was found that can be mutated, use TopLink methods to
         * modify the value stored in the object for that mapping.  Otherwise
         * do nothing.
         */
        if (mutatableMapping != null) {
            mutatableMapping.setAttributeValueInObject(
                objectToBeMutated,
                mutatableMapping.getAttributeValueFromObject(
                    objectToBeMutated) + mutationString);
        }
        else {
            // Can't necessarily throw error/warning as some projects
            // (i.e. LOB project) have descriptors that are not simple to mutate
        }

        return objectToBeMutated;
    }

    /**
     * @see #setMakesTrivialUpdate(boolean)
     */
    public boolean makesTrivialUpdate() {
        return makesTrivialUpdate;
    }

    /**
     * @see #setTestShouldMutate(boolean)
     */
    public boolean testShouldMutate() {
        return testShouldMutate;
    }

    @Override
    public void reset() {
        if (bindAllParametersOriginal != null) {
            getSession().getLogin().setShouldBindAllParameters(bindAllParametersOriginal);
        }
        super.reset();
    }

    /**
     * A trivial update is writing the same version of an object to the
     * database as exists on the database.  Normally in this test the object
     * passed to the constructor is used only to read the version of itself on
     * the database.  This version from the database is then written to the
     * database: a trivial update.  If this flag is set and originalObject is
     * different from but has the same primary key as an object on the database,
     * then a non-trivial update will occur.
     * Warning: If you modify the objects passed to this
     * test, do not obtain them from the population manager, as they may become
     * corrupted for other users.
     */
    public void setMakesTrivialUpdate(boolean value) {
        this.makesTrivialUpdate = value;
    }

    /**
     * Some subclasses of WriteObjectTest will not return the correct results if
     * the object is mutated, for example tests that pass null values and expect
     * nulls to be returned.  If this flag is set then the object will not be
     * mutated before attempting to write to the database.
     */
    public void setTestShouldMutate(boolean value) {
        this.testShouldMutate = value;
    }

    /**
     * Allows one to set bindAllParameters to true on a test by test basis.
     * This works only for simple sessions, and could cause this simple test to
     * run much slower than before.
     */
    public void setShouldBindAllParameters(boolean value) {
        bindAllParameters = value;
    }

    @Override
    protected void setup() {
        if (shouldBindAllParameters() != null) {
            bindAllParametersOriginal = getSession().getLogin().shouldBindAllParameters();
            getSession().getLogin().setShouldBindAllParameters(shouldBindAllParameters());
        }
        super.setup();

        this.query = new ReadObjectQuery();
        this.query.setSelectionObject(this.originalObject);

        /* Must ensure that the object is from the database for updates. */
        this.objectToBeWritten = getSession().executeQuery(this.query);
        if (this.query.getDescriptor().shouldIsolateProtectedObjectsInUnitOfWork() && getSession().isClientSession()){
            //must get entity from server session and not the isolated session.
            this.objectToBeWritten = ((ClientSession)getSession()).getParent().getIdentityMapAccessor().getFromIdentityMap(this.objectToBeWritten);
        }
        if (this.objectToBeWritten == null) {
            this.objectToBeWritten = this.originalObject;
            this.query = new ReadObjectQuery();
            this.query.setSelectionObject(this.originalObject);
        }

        if (!makesTrivialUpdate()) {
            this.objectToBeWritten = this.originalObject;
        }
    }

    public Boolean shouldBindAllParameters() {
        return bindAllParameters;
    }


    /**
     * The test() method will, if required, pass the object to the
     * findAndMutateDirectToFieldMappingInObject method, and will then attempt
     * to write the object to the database.
     */
    @Override
    protected void test() {

        if (makesTrivialUpdate() && testShouldMutate()) {
            // Only want to do this if the update is trivial
            // Otherwise there are already changes in the object that
            // will generate SQL
            this.objectToBeWritten =
                this.findAndMutateDirectToFieldMappingInObject(
                    this.objectToBeWritten, false);
        }

        getDatabaseSession().writeObject(this.objectToBeWritten);
    }

    /**
     * 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() {
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
        this.objectFromDatabase = getSession().executeQuery(this.query);

        if (!(compareObjects(this.objectToBeWritten, this.objectFromDatabase))) {
            throw new TestErrorException("The object inserted into the database, '"
                + this.objectFromDatabase + "' does not match the original, '"
                + this.objectToBeWritten + "'.");
        }
    }
}
