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

import commonj.sdo.DataObject;
import commonj.sdo.Property;
import commonj.sdo.Type;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import junit.textui.TestRunner;
import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDOType;
import org.eclipse.persistence.testing.sdo.SDOTestCase;

public class SDODataObjectOpenContentBug6011530TestCases extends SDOTestCase {
    private DataObject rootDataObject;
    private DataObject rootDataObject2;
    private DataObject childDataObject;
    private DataObject childDataObject2;

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

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

    @Override
    public void setUp() {
        super.setUp();
        Type stringType = SDOConstants.SDO_STRING;

        DataObject addressType = defineType("my.uri", "address");
        addProperty(addressType, "city", stringType, false, false, true);
        addProperty(addressType, "street", stringType, false, false, true);

        Type addressSDOType = typeHelper.define(addressType);

        DataObject empType = defineType("my.uri", "employee");
        addProperty(empType, "name", stringType, false, false, true);
        addProperty(empType, "address", addressSDOType, true, false, true);
        empType.set("open", true);

        Type empSDOType = typeHelper.define(empType);

        rootDataObject = dataFactory.create(empSDOType);
        rootDataObject.set("name", "Bob Smith");

        rootDataObject2 = dataFactory.create(empSDOType);
        rootDataObject2.set("name", "JaneDoe");
        childDataObject = dataFactory.create(addressSDOType);
        childDataObject2 = dataFactory.create(addressSDOType);
    }

    public void testSetDefineOpenContent() throws Exception {
        rootDataObject.set("addressOpenContent", childDataObject);
        Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
        assertNotNull(openProp);
        assertTrue(openProp.isOpenContent());
        assertTrue(openProp.isContainment());
        assertFalse(openProp.isMany());
        assertEquals(childDataObject.getType(), openProp.getType());

    }

     public void testSetDefineOpenContentManyProperty() throws Exception {
        List value = new ArrayList();
        value.add(childDataObject);
        rootDataObject.set("addressOpenContent", value);
        Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
        assertNotNull(openProp);
        assertTrue(openProp.isOpenContent());
        assertTrue(openProp.isContainment());
        assertTrue(openProp.isMany());
        assertEquals(childDataObject.getType(), openProp.getType());
    }

      public void testSetDefineOpenContentManyPropertyContainmentChild() throws Exception {
        SDOType typeType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.TYPE);

        List value = new ArrayList();
        Type addressSDOType = typeHelper.getType("my.uri", "address");
        DataObject childDataObjectContainment = dataFactory.create(addressSDOType);

        DataObject someOther = dataFactory.create(typeType);
        someOther.set("name", "someOther");
        someOther.set("uri", "my.uri");
        addProperty(someOther,"test", addressSDOType, true, false, true);
        Type someOtherParentType = typeHelper.define(someOther);
        DataObject someOtherParentDO = dataFactory.create(someOtherParentType);
        someOtherParentDO.set("test", childDataObjectContainment);

        value.add(childDataObjectContainment);
        rootDataObject.set("addressOpenContent", value);
        Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
        assertNotNull(openProp);
        assertTrue(openProp.isOpenContent());
        assertFalse(openProp.isContainment());
        assertTrue(openProp.isMany());
        assertEquals(childDataObject.getType(), openProp.getType());
    }

    public void testSetDefineOpenContentManySimpleProperty() throws Exception {
        List value = new ArrayList();
        value.add(Integer.valueOf(4));
        rootDataObject.set("addressOpenContent", value);
        Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
        assertNotNull(openProp);
        assertTrue(openProp.isOpenContent());
        assertFalse(openProp.isContainment());
        assertTrue(openProp.isMany());
        assertEquals(SDOConstants.SDO_INTOBJECT, openProp.getType());

        assertTrue(rootDataObject.isSet("addressOpenContent"));
        rootDataObject.unset("addressOpenContent");
        assertFalse(rootDataObject.isSet("addressOpenContent"));
    }

     public void testSetDefineOpenContentManySimplePropertyEmpty() throws Exception {
        List value = new ArrayList();
        rootDataObject.set("addressOpenContent", value);
        Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
        assertNull(openProp);

    }

     public void testSetDefineOpenContentManySimplePropertyNullInList() throws Exception {
        List value = new ArrayList();
        value.add(null);
        rootDataObject.set("addressOpenContent", value);
        Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
        assertNull(openProp);
    }

    public void testSetDefineOpenContentContained() throws Exception {
        rootDataObject2.set("address", childDataObject2);

        rootDataObject.set("addressOpenContent", childDataObject2);
        Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
        assertNotNull(openProp);
        assertTrue(openProp.isOpenContent());
        assertFalse(openProp.isContainment());
        assertFalse(openProp.isMany());
        assertEquals(childDataObject.getType(), openProp.getType());

    }

    public void testSetDefineOpenContentMany() throws Exception {
        List theList = new ArrayList();
        theList.add(childDataObject);
        theList.add(childDataObject2);

        rootDataObject.set("addressOpenContent", theList);
        Property openProp = rootDataObject.getInstanceProperty("addressOpenContent");
        assertNotNull(openProp);
        assertTrue(openProp.isOpenContent());
        assertTrue(openProp.isContainment());
        assertTrue(openProp.isMany());
        assertEquals(childDataObject.getType(), openProp.getType());
    }

    public void testSetDefineOpenContentSimple() throws Exception {
        rootDataObject.set("stringOpenContent", "someString");
        Property openProp = rootDataObject.getInstanceProperty("stringOpenContent");
        assertNotNull(openProp);
        assertTrue(openProp.isOpenContent());
        assertFalse(openProp.isContainment());
        assertFalse(openProp.isMany());
        assertEquals(SDOConstants.SDO_STRING, openProp.getType());

    }

    public void testSetDefineOpenContentSimple2() throws Exception {
        BigInteger value = new BigInteger("123");
        rootDataObject.set("stringOpenContent", value);
        Property openProp = rootDataObject.getInstanceProperty("stringOpenContent");
        assertNotNull(openProp);
        assertTrue(openProp.isOpenContent());
        assertFalse(openProp.isContainment());
        assertFalse(openProp.isMany());
        assertEquals(SDOConstants.SDO_INTEGER, openProp.getType());
    }

}
