/*
 * Copyright (c) 2018, 2020 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
 */

package org.eclipse.persistence.testing.sdo.model.property;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.persistence.sdo.SDOType;

import commonj.sdo.DataObject;
import commonj.sdo.helper.DataFactory;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.helper.TypeHelper;
import commonj.sdo.helper.XMLDocument;
import commonj.sdo.helper.XMLHelper;

import junit.framework.TestCase;

/**
 * Test the hashCode and equality methods on SDOProperty.
 */
public class SDOPropertyEqualityTests extends TestCase {
    /**
     * This test does the following:
     *   1) Define a DataObject with a single String property, 'name'
     *   2) Create two instances of this DataObject, each with a different 'name'
     *   3) Add the two DataObjects to a list named 'result'
     *   4) Create a wrapper DataObject
     *   5) Set the 'result' list on the wrapper DataObject
     *   6) Create an XML document from the wrapper DataObject
     *   7) Save the document to a StringWriter
     *   8) Load the document
     *   9) Get the root DataObject from the document
     *  10) Verify that the root DataObject has a 'result' list containing two entries
     *
     * If the hashCode and equals method on SDOProperty do not work properly, the root DataObject
     * will have return a 'result' list with only one entry.
     */
    public void testSameNameProperty() {
        boolean exception = false;
        String msg = "";
        List resultList = null;

        try {
            setUpDO();

            List<DataObject> result = queryDO();
            // The HelperContext corresponding to the DataObjects in the query result.
            HelperContext helperContext = ((SDOType) result.get(0).getType()).getHelperContext();

            DataObject wrapperDO = helperContext.getDataFactory().create("org.eclipse.persistence.sdo", "OpenSequencedType");
            wrapperDO.setList("result", result);

            XMLDocument xmlDocument = helperContext.getXMLHelper().createDocument(wrapperDO, "http://www.example.org", "ROOT");
            StringWriter stringWriter = new StringWriter();
            XMLHelper.INSTANCE.save(xmlDocument, stringWriter, null);

            StringReader stringReader = new StringReader(stringWriter.toString());
            XMLDocument resultDocument = helperContext.getXMLHelper().load(stringReader, null, null);
            DataObject resultDO = resultDocument.getRootObject();

            resultList = resultDO.getList("result");
        } catch (Exception x) {
            exception = true;
            msg = x.getMessage();
        }
        assertFalse("An unexpected exception occurred: " + msg, exception);
        assertTrue("Expected 2 list entries, but was " + resultList.size() , resultList.size() == 2);
    }

    private void setUpDO() {
        DataObject itemTypeDO = DataFactory.INSTANCE.create("commonj.sdo", "Type");
        itemTypeDO.set("name", "Item");
        itemTypeDO.set("uri", "org.example");
        itemTypeDO.setBoolean("dataType", false);

        DataObject namePropertyDO = DataFactory.INSTANCE.create("commonj.sdo", "Property");
        namePropertyDO.set("name", "name");
        namePropertyDO.set("type", TypeHelper.INSTANCE.getType("commonj.sdo", "String"));
        itemTypeDO.getList("property").add(namePropertyDO);

        TypeHelper.INSTANCE.define(itemTypeDO);
    }

    private List<DataObject> queryDO() {
        List result = new ArrayList<DataObject>();

        DataObject item1DO = DataFactory.INSTANCE.create("org.example", "Item");
        item1DO.set("name", "Telephone");
        result.add(item1DO);

        DataObject item2DO = DataFactory.INSTANCE.create("org.example", "Item");
        item2DO.set("name", "Extension Cord");
        result.add(item2DO);

        return result;
    }
}
