/*
 * 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 java.util.List;
import junit.textui.TestRunner;
import commonj.sdo.DataObject;
import commonj.sdo.Property;
import commonj.sdo.helper.XMLDocument;

public class ChangeSummaryXSDWithCSonRootUnsetComplexSingleAtRootTest extends ChangeSummaryOnRootTestCases {
    @Override
    protected String getControlFileName() {
        return ("./org/eclipse/persistence/testing/sdo/helper/xmlhelper/changesummary/PurchaseOrderDeepWithCSonRootUnsetComplexSingleAtRoot.xml");
    }

    @Override
    protected String getControlFileName2() {
        return getControlFileName();
    }

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

    public static void main(String[] args) {
        String[] arguments = { "-c", "org.eclipse.persistence.testing.sdo.model.changesummary.ChangeSummaryXSDWithCSonRootUnsetComplexSingleAtRootTest" };
        TestRunner.main(arguments);
    }

    @Override
    public void setUp() {
        super.setUp();// watch setup redundancy
    }

    @Override
    protected void verifyAfterLoad(XMLDocument document) {
        super.verifyAfterLoad(document);
        // replace global object with one from xml file (with cs pre-populated)
        rootObject = document.getRootObject();
        cs = rootObject.getChangeSummary();
        DataObject shipToDO = null;//rootObject.getDataObject("shipTo");
        DataObject yardDO = null;//shipToDO.getDataObject("yard");
        Property containmentProp = null;//shipToDO.getContainmentProperty();

        //List phoneList = shipToDO.getList("phone");
        DataObject phone1 = null;//(DataObject)phoneList.get(0);
        DataObject phone2 = null;//(DataObject)phoneList.get(1);

        verifyCSonRootDetachUnsetComplexSingleAtRoot(true, shipToDO, containmentProp, yardDO, phone1, phone2);
    }

    public void testDetachComplexSingleBelowRoot() {
        defineTypes();
        // 1. read in model from a populated XML file - via setup()
        // 2. rootObject will be in pre-operation state
        // 3. get references to the original object tree - before operation is performed
        // 4. [perform operation]
        // 5. compare new modified model with original objects - in memory
        DataObject shipToDO = rootObject.getDataObject("shipTo");
        Property containmentProp = shipToDO.getContainmentProperty();
        DataObject yardDO = shipToDO.getDataObject("yard");
        List phoneList = shipToDO.getList("phone");
        DataObject phone1 = (DataObject)phoneList.get(0);
        DataObject phone2 = (DataObject)phoneList.get(1);
        cs.beginLogging();
        rootObject.unset("shipTo");

        verifyCSonRootDetachUnsetComplexSingleAtRoot(false, shipToDO, containmentProp, yardDO, phone1, phone2);
    }

    /*
        protected void verifyAfterLoad(XMLDocument document) {
            super.verifyAfterLoad(document);
            // replace global object with one from xml file (with cs pre-populated)
            rootObject = document.getRootObject();
            cs = rootObject.getChangeSummary();
            DataObject shipToDO = rootObject.getDataObject("shipTo");

            assertCSonRootUnsetComplexSingleAtRoot(true, shipToDO);
        }

        public void testUnsetComplexSingleBelowRoot() {
            // 1. read in model from a populated XML file - via setup()
            // 2. rootObject will be in pre-operation state
            // 3. get references to the original object tree - before operation is performed
            // 4. [perform operation]
            // 5. compare new modified model with original objects - in memory
            DataObject shipToDO = rootObject.getDataObject("shipTo");
            cs.beginLogging();
            Property containmentProp = shipToDO.getContainmentProperty();
            shipToDO.unset(containmentProp);

            assertCSonRootUnsetComplexSingleAtRoot(false, shipToDO);
        }*/
}
