/*
 * 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.sdo.model.changesummary;

import commonj.sdo.ChangeSummary;
import commonj.sdo.DataObject;
import org.eclipse.persistence.sdo.SDOChangeSummary;
import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDODataObject;
import org.eclipse.persistence.sdo.SDOProperty;
import org.eclipse.persistence.sdo.SDOType;
import org.eclipse.persistence.testing.sdo.SDOTestCase;

public class ChangeSummaryCreatedModifiedDeletedTestCase extends SDOTestCase {
    protected static final String URINAME = "root_uri";
    protected static final String TYPENAME = "rootTypeName";
    protected static final String PROPERTY_NAME = "PName";
    protected static final String CONTAINED_TYPENAME = "ContainedTypeName";
    protected static final String CONTAINED_PROPERTYNAME = "ContainedPName";
    protected SDODataObject root;
    protected SDOType rootType;
    protected SDOChangeSummary changeSummaryA;
    protected SDOProperty rootContainingPropertyB;
    protected SDOProperty rootContainingPropertyC;
    protected SDOProperty rootChangeSummaryProperty;
    protected SDODataObject dataObjectB;
    protected SDOType type_B;
    protected SDOProperty propertyB;
    protected SDOChangeSummary changeSummaryB;
    protected SDOProperty changeSummaryPropertyB;
    protected SDODataObject dataObjectC;
    protected SDOType type_C;
    protected SDOProperty propertyC;
    protected SDOChangeSummary changeSummaryC;
    protected SDOProperty changeSummaryPropertyC;
    protected SDODataObject dataObjectD;
    protected SDOType type_D;
    protected SDOProperty propertyD;
    protected SDODataObject dataObjectE;
    protected SDOType type_E;
    protected SDOProperty propertyE;
    protected SDODataObject root1;
    protected SDOType type_root1;
    protected SDOProperty p_root1;
    protected SDODataObject dataObjectF;
    protected SDOType type_F;
    protected SDOProperty p_F;

    public ChangeSummaryCreatedModifiedDeletedTestCase(String name) {
        super(name);
    }

    @Override
    public void setUp() {
        super.setUp(); // watch setup redundancy
        DataObject rootTypeDO = defineType(URINAME, TYPENAME);
        rootType = (SDOType)typeHelper.define(rootTypeDO);

        SDOType changeSummaryType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.CHANGESUMMARY);
        SDOType dataObjectType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.DATAOBJECT);

        rootContainingPropertyB = setUpProperty("propertyA-B", true, dataObjectType, rootType);
        rootContainingPropertyC = setUpProperty("propertyA-C", true, dataObjectType, rootType);
        rootChangeSummaryProperty = setUpProperty("changeSummaryA", true, changeSummaryType, null);

    }

    protected SDOProperty setUpProperty(String name, boolean containment, SDOType propertyType, SDOType owner) {
        SDOProperty property = new SDOProperty(aHelperContext);
        property.setName(name);
        property.setContainment(containment);
        property.setType(propertyType);
        if (owner != null) {
            owner.addDeclaredProperty(property);
        }
        return property;
    }

    /*
     * root
     *   -> B
     *        -> CS-B
     *        -> D (String)
     *   -> C
     *        -> CS-C
     */
    protected void buildTree() {
        SDOType changeSummaryType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.CHANGESUMMARY);
        SDOType dataObjectType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.DATAOBJECT);

        DataObject type_BDO = defineType("B_uri", "B");
        type_B = (SDOType)typeHelper.define(type_BDO);

        propertyB = setUpProperty("propertyB", true, dataObjectType, type_B);
        changeSummaryPropertyB = setUpProperty("changeSummaryB", false, changeSummaryType, type_B);

        DataObject type_CDO = defineType("C_uri", "C");
        type_C = (SDOType)typeHelper.define(type_CDO);

        propertyC = setUpProperty("propertyC", true, dataObjectType, type_C);
        changeSummaryPropertyC = setUpProperty("changeSummaryC", false, changeSummaryType, type_C);

        DataObject type_DDO = defineType("D_uri", "D");
        type_D = (SDOType)typeHelper.define(type_DDO);

        propertyD = setUpProperty("propertyD", false, SDOConstants.SDO_STRING, type_D);

        root = (SDODataObject)dataFactory.create(rootType);
        dataObjectB = root.createDataObject(rootContainingPropertyB, type_B);
        dataObjectC = root.createDataObject(rootContainingPropertyC, type_C);
        dataObjectD = dataObjectB.createDataObject(propertyB, type_D);
    }

    protected void checkOldSettingsSizeTree(String values, SDOChangeSummary aCS,//
                                            SDODataObject aDO1, SDODataObject aDO2, SDODataObject aDO3, SDODataObject aDO4) {
        assertEquals(Integer.parseInt(values.substring(0, 1)), aCS.getOldValues(aDO1).size());
        assertEquals(Integer.parseInt(values.substring(1, 2)), aCS.getOldValues(aDO2).size());
        assertEquals(Integer.parseInt(values.substring(2, 3)), aCS.getOldValues(aDO3).size());
        assertEquals(Integer.parseInt(values.substring(3, 4)), aCS.getOldValues(aDO4).size());
    }

    protected void checkOldContainer(SDOChangeSummary aCS,//
                                     SDODataObject aDO1, Object anObject1,//
                                     SDODataObject aDO2, Object anObject2,//
                                     SDODataObject aDO3, Object anObject3,//
                                     SDODataObject aDO4, Object anObject4) {
        assertEquals(anObject1, aCS.getOldContainer(aDO1));
        assertEquals(anObject2, aCS.getOldContainer(aDO2));
        assertEquals(anObject3, aCS.getOldContainer(aDO3));
        assertEquals(anObject4, aCS.getOldContainer(aDO4));
    }

    /*
     * root
     *   -> B
     *        -> CS-B
     *        -> D
     *             -> E
     *                  -> string
     *   -> C
     *        -> CS-C
     */
    protected void buildTreeWith4LevelsOfProperties() {
        SDOType changeSummaryType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.CHANGESUMMARY);
        SDOType dataObjectType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.DATAOBJECT);

        DataObject type_BDO = defineType("B_uri", "B");
        type_B = (SDOType)typeHelper.define(type_BDO);

        propertyB = setUpProperty("propertyB", true, dataObjectType, type_B);
        changeSummaryPropertyB = setUpProperty("changeSummaryB", false, changeSummaryType, type_B);

        DataObject type_CDO = defineType("C_uri", "C");
        type_C = (SDOType)typeHelper.define(type_CDO);

        propertyC = setUpProperty("propertyC", true, dataObjectType, type_C);
        changeSummaryPropertyC = setUpProperty("changeSummaryC", false, changeSummaryType, type_C);

        DataObject type_DDO = defineType("D_uri", "D");
        type_D = (SDOType)typeHelper.define(type_DDO);

        propertyD = setUpProperty("propertyD", true, dataObjectType, type_D);

        DataObject type_EDO = defineType("E_uri", "E");
        type_E = (SDOType)typeHelper.define(type_EDO);
        propertyE = setUpProperty("propertyE", false, SDOConstants.SDO_STRING, type_E);

        root = (SDODataObject)dataFactory.create(rootType);
        dataObjectB = root.createDataObject(rootContainingPropertyB, type_B);
        dataObjectC = root.createDataObject(rootContainingPropertyC, type_C);
        dataObjectD = dataObjectB.createDataObject(propertyB, type_D);
        dataObjectE = dataObjectD.createDataObject(propertyD, type_E);

    }

    protected void checkOldSettingsSizeTree(String values, SDOChangeSummary aCS,//
                                            SDODataObject aDO1, SDODataObject aDO2, SDODataObject aDO3, SDODataObject aDO4, SDODataObject aDO5) {
        checkOldSettingsSizeTree(values, aCS, aDO1, aDO2, aDO3, aDO4);
        assertEquals(Integer.parseInt(values.substring(5, 6)), aCS.getOldValues(aDO5).size());
    }

    protected void checkOldContainer(SDOChangeSummary aCS,//
                                     SDODataObject aDO1, Object anObject1,//
                                     SDODataObject aDO2, Object anObject2,//
                                     SDODataObject aDO3, Object anObject3,//
                                     SDODataObject aDO4, Object anObject4,//
                                     SDODataObject aDO5, Object anObject5) {
        checkOldContainer(aCS,//
                          aDO1, anObject1,//
                          aDO2, anObject2,//
                          aDO3, anObject3,//
                          aDO4, anObject4);
        assertEquals(anObject5, aCS.getOldContainer(aDO5));
    }

    protected void buildTreeWithoutChildChangeSummaries() {
        SDOType dataObjectType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.DATAOBJECT);

        DataObject type_BDO = defineType("B_uri", "B");
        type_B = (SDOType)typeHelper.define(type_BDO);

        propertyB = setUpProperty("propertyB", true, dataObjectType, type_B);

        DataObject type_CDO = defineType("C_uri", "C");
        type_C = (SDOType)typeHelper.define(type_CDO);
        propertyC = setUpProperty("propertyC", true, dataObjectType, type_C);

        DataObject type_DDO = defineType("D_uri", "D");
        type_D = (SDOType)typeHelper.define(type_DDO);
        propertyD = setUpProperty("propertyD", false, SDOConstants.SDO_STRING, type_D);

        dataObjectB = root.createDataObject(rootContainingPropertyB, type_B);
        dataObjectC = root.createDataObject(rootContainingPropertyC, type_C);
        dataObjectD = dataObjectB.createDataObject(propertyB, type_D);
    }

    protected void buildTreeWithoutChangeSummary() {
        SDOType dataObjectType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.DATAOBJECT);

        DataObject type_root1DO = defineType("root1_uri", "root1");
        type_root1 = (SDOType)typeHelper.define(type_root1DO);

        p_root1 = setUpProperty("p_root1", true, dataObjectType, type_root1);
        root1 = (SDODataObject)dataFactory.create(type_root1);

        DataObject type_FDO = defineType("F_uri", "F");
        type_F = (SDOType)typeHelper.define(type_FDO);

        p_F = setUpProperty("p_F", false, SDOConstants.SDO_STRING, type_F);
        dataObjectF = root1.createDataObject(p_root1, type_F);
        dataObjectF.set(p_F, "test");
    }
}
