/*
 * 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:
//     bdoughan - Jan 27/2009 - 1.1 - Initial implementation
package org.eclipse.persistence.testing.sdo.helper.jaxbhelper.helpercontext;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.SchemaOutputResolver;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.persistence.exceptions.SDOException;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.sdo.SDODataObject;
import org.eclipse.persistence.sdo.helper.SDODataFactory;
import org.eclipse.persistence.sdo.helper.SDOXMLHelper;
import org.eclipse.persistence.sdo.helper.delegates.SDODataFactoryDelegator;
import org.eclipse.persistence.sdo.helper.delegates.SDOTypeHelperDelegator;
import org.eclipse.persistence.sdo.helper.delegates.SDOXMLHelperDelegator;
import org.eclipse.persistence.sdo.helper.delegates.SDOXSDHelperDelegator;
import org.eclipse.persistence.sdo.helper.jaxb.JAXBHelperContext;
import org.eclipse.persistence.sdo.helper.jaxb.JAXBValueStore;
import org.eclipse.persistence.testing.sdo.SDOTestCase;

import commonj.sdo.DataObject;
import commonj.sdo.Type;
import commonj.sdo.helper.DataFactory;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.helper.TypeHelper;
import commonj.sdo.helper.XMLHelper;
import commonj.sdo.helper.XSDHelper;
import commonj.sdo.impl.HelperProvider;

public class HelperContextTestCases extends SDOTestCase {

    private JAXBHelperContext jaxbHelperContext;

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

    @Override
    public void setUp() {
        try {
            Class[] classes = new Class[1];
            classes[0] = Root.class;
            JAXBContext jaxbContext = JAXBContext.newInstance(classes);
            jaxbHelperContext = new JAXBHelperContext(jaxbContext);
            jaxbHelperContext.makeDefaultContext();
            JAXBSchemaOutputResolver sor = new JAXBSchemaOutputResolver();
            jaxbContext.generateSchema(sor);
            String xmlSchema = sor.getSchema();
            jaxbHelperContext.getXSDHelper().define(xmlSchema);
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void testGetType() {
        Type pojoType = jaxbHelperContext.getType(Root.class);
        assertNotNull(pojoType);

        Type rootType = jaxbHelperContext.getTypeHelper().getType("urn:helpercontext", "root");
        assertSame(rootType, pojoType);
    }

    public void testGetClass() {
        Type rootType = jaxbHelperContext.getTypeHelper().getType("urn:helpercontext", "root");
        Class pojoClass = jaxbHelperContext.getClass(rootType);
        assertSame(Root.class, pojoClass);
    }

    public void testGetClassNull() {
        Class pojoClass = jaxbHelperContext.getClass(null);
        assertNull(pojoClass);
    }

    public void testGetClassNegative() {
        try {
            Type propertyType = jaxbHelperContext.getTypeHelper().getType("commonj.sdo", "Property");
            Class pojoClass = jaxbHelperContext.getClass(propertyType);
        } catch(SDOException e) {
            assertEquals(SDOException.SDO_JAXB_NO_DESCRIPTOR_FOR_TYPE, e.getErrorCode());
            return;
        }
        fail("An exception should have been thrown, but was not.");
    }

    public void testDataFactoryGetHelperContext() {
        SDODataFactoryDelegator sdoDataFactoryDelegator = (SDODataFactoryDelegator) DataFactory.INSTANCE;

        HelperContext testDefaultHelperContext = sdoDataFactoryDelegator.getHelperContext();
        assertSame(HelperProvider.getDefaultContext(), testDefaultHelperContext);

        HelperContext testHelperContext = sdoDataFactoryDelegator.getDataFactoryDelegate().getHelperContext();
        assertSame(jaxbHelperContext, testHelperContext);
    }

    public void testTypeHelperGetHelperContext() {
        SDOTypeHelperDelegator sdoTypeHelperDelegator = (SDOTypeHelperDelegator) TypeHelper.INSTANCE;

        HelperContext testDefaultHelperContext = sdoTypeHelperDelegator.getHelperContext();
        assertSame(HelperProvider.getDefaultContext(), testDefaultHelperContext);

        HelperContext testHelperContext = sdoTypeHelperDelegator.getTypeHelperDelegate().getHelperContext();
        assertSame(jaxbHelperContext, testHelperContext);
    }

    public void testXMLHelperGetHelperContext() {
        SDOXMLHelperDelegator sdoXMLHelperDelegator = (SDOXMLHelperDelegator) XMLHelper.INSTANCE;

        HelperContext testDefaultHelperContext = sdoXMLHelperDelegator.getHelperContext();
        assertSame(HelperProvider.getDefaultContext(), testDefaultHelperContext);

        HelperContext testHelperContext = sdoXMLHelperDelegator.getXMLHelperDelegate().getHelperContext();
        assertSame(jaxbHelperContext, testHelperContext);
    }

    public void testXSDHelperGetHelperContext() {
        SDOXSDHelperDelegator sdoXSDHelperDelegator = (SDOXSDHelperDelegator) XSDHelper.INSTANCE;

        HelperContext testDefaultHelperContext = sdoXSDHelperDelegator.getHelperContext();
        assertSame(HelperProvider.getDefaultContext(), testDefaultHelperContext);

        HelperContext testHelperContext = sdoXSDHelperDelegator.getXSDHelperDelegate().getHelperContext();
        assertSame(jaxbHelperContext, testHelperContext);
    }

    public void testWrap() {
        Root root = new Root();
        SDODataObject rootDO = (SDODataObject) jaxbHelperContext.wrap(root);
        assertNotNull(rootDO);

        assertSame(JAXBValueStore.class, rootDO._getCurrentValueStore().getClass());
    }

    public void testWrapTwice() {
        Root root = new Root();

        SDODataObject rootDO1 = (SDODataObject) jaxbHelperContext.wrap(root);
        assertNotNull(rootDO1);

        SDODataObject rootDO2 = (SDODataObject) jaxbHelperContext.wrap(root);
        assertNotNull(rootDO2);

        assertSame(rootDO1, rootDO2);
    }

    public void testWrapCollection() {
        Root root1 = new Root();
        Root root2 = new Root();
        Set collection = new HashSet(2);
        collection.add(root1);
        collection.add(root2);
        List<DataObject> wrappedList = jaxbHelperContext.wrap(collection);

        for(DataObject dataObject: wrappedList) {
            assertNotNull(dataObject);
            assertSame(JAXBValueStore.class, ((SDODataObject) dataObject)._getCurrentValueStore().getClass());
        }
    }

    public void testWrapNullCollection() {
        List<DataObject> wrappedList = jaxbHelperContext.wrap(null);
        assertNotNull(wrappedList);
        assertEquals(0, wrappedList.size());
    }

    public void testWrapEmptyCollection() {
        Set collection = new HashSet(0);
        List<DataObject> wrappedList = jaxbHelperContext.wrap(collection);
        assertNotNull(wrappedList);
        assertEquals(0, wrappedList.size());
    }

    public void testWrapNull() {
        DataObject nullDO = jaxbHelperContext.wrap((Object) null);
        assertNull(nullDO);
    }

    public void testWrapUnknownObject() {
        boolean fail = true;
        try {
            Object unknownObject = "FOO";
            jaxbHelperContext.wrap(unknownObject);
        } catch(SDOException e) {
            if(e.getErrorCode() == SDOException.SDO_JAXB_NO_TYPE_FOR_CLASS) {
                fail = false;
            }
        }
        if(fail) {
            fail();
        }
    }

    public void testWrapObjectWithoutSchemaReference() {
        boolean fail = true;
        try {
            org.eclipse.persistence.jaxb.JAXBContext jaxbContext = (org.eclipse.persistence.jaxb.JAXBContext) jaxbHelperContext.getJAXBContext();
            XMLDescriptor xmlDescriptor = (XMLDescriptor) jaxbContext.getXMLContext().getSession(Root.class).getDescriptor(Root.class);
            xmlDescriptor.setSchemaReference(null);
            jaxbHelperContext.wrap(new Root());
        } catch(SDOException e) {
            if(e.getErrorCode() == SDOException.SDO_JAXB_NO_SCHEMA_REFERENCE) {
                fail = false;
            }
        }
        if(fail) {
            fail();
        }
    }

    public void testWrapObjectWithoutSchemaContext() {
        boolean fail = true;
        try {
            org.eclipse.persistence.jaxb.JAXBContext jaxbContext = (org.eclipse.persistence.jaxb.JAXBContext) jaxbHelperContext.getJAXBContext();
            XMLDescriptor xmlDescriptor = (XMLDescriptor) jaxbContext.getXMLContext().getSession(Root.class).getDescriptor(Root.class);
            xmlDescriptor.getSchemaReference().setSchemaContext(null);
            xmlDescriptor.getSchemaReference().setSchemaContextAsQName(null);
            jaxbHelperContext.wrap(new Root());
        } catch(SDOException e) {
            if(e.getErrorCode() == SDOException.SDO_JAXB_NO_SCHEMA_CONTEXT) {
                fail = false;
            }
        }
        if(fail) {
            fail();
        }
    }

    public void testWrapObjectWithIncorrectSchemaContext() {
        boolean fail = true;
        try {
            org.eclipse.persistence.jaxb.JAXBContext jaxbContext = (org.eclipse.persistence.jaxb.JAXBContext) jaxbHelperContext.getJAXBContext();
            XMLDescriptor xmlDescriptor = (XMLDescriptor) jaxbContext.getXMLContext().getSession(Root.class).getDescriptor(Root.class);
            xmlDescriptor.getSchemaReference().setSchemaContext("/INVALID");
            xmlDescriptor.getSchemaReference().setSchemaContextAsQName(null);
            jaxbHelperContext.wrap(new Root());
        } catch(SDOException e) {
            if(e.getErrorCode() == SDOException.SDO_JAXB_NO_TYPE_FOR_CLASS_BY_SCHEMA_CONTEXT) {
                fail = false;
            }
        }
        if(fail) {
            fail();
        }
    }

    public void testUnwrap() {
        Root root = new Root();
        SDODataObject rootDO = (SDODataObject) jaxbHelperContext.wrap(root);
        assertSame(root, jaxbHelperContext.unwrap(rootDO));
    }

    public void testUnwrapNull() {
        Object object = jaxbHelperContext.unwrap((DataObject) null);
        assertNull(object);
    }

    public void testUnwrapCollection() {
        Root root1 = new Root();
        Root root2 = new Root();
        Set collection = new HashSet(2);
        collection.add(root1);
        collection.add(root2);
        Collection<DataObject> wrappedEntities = jaxbHelperContext.wrap(collection);

        List<Object> entities = jaxbHelperContext.unwrap(wrappedEntities);
        assertNotNull(entities);
        assertEquals(2, entities.size());
        assertTrue(entities.contains(root1));
        assertTrue(entities.contains(root2));
    }

    public void testUnwrapNullCollection() {
        List<Object> entities = jaxbHelperContext.unwrap((Collection) null);
        assertNotNull(entities);
        assertEquals(0, entities.size());
    }

    public void testUnwrapEmptyCollection() {
        Collection wrappedCollection = new HashSet(0);
        List entities = jaxbHelperContext.unwrap(wrappedCollection);
        assertNotNull(entities);
        assertEquals(0, entities.size());
    }

    @Override
    public void tearDown() {
    }

    private class JAXBSchemaOutputResolver extends SchemaOutputResolver {

        private StringWriter schemaWriter;

        public String getSchema() {
            return schemaWriter.toString();
        }

        @Override
        public Result createOutput(String arg0, String arg1) throws IOException {
            schemaWriter = new StringWriter();
            return new StreamResult(schemaWriter);
        }

    }

}
