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

// Contributors:
// dmccann - Jan 30/2009 - 1.1 - Initial implementation
package org.eclipse.persistence.testing.sdo.helper.helpercontext;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

import junit.textui.TestRunner;

import org.eclipse.persistence.sdo.SDODataObject;
import org.eclipse.persistence.sdo.helper.DataObjectInputStream;
import org.eclipse.persistence.sdo.helper.SDOHelperContext;
import org.eclipse.persistence.sdo.helper.SDOTypeHelper;
import org.eclipse.persistence.sdo.helper.SDOXMLHelper;
import org.eclipse.persistence.sdo.helper.SDOXSDHelper;

import commonj.sdo.DataObject;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.impl.HelperProviderImpl;

public class UserSetContextMapTestCases extends SDOHelperContextTestCases {
    protected final String FILE_NAME = tempFileDir + "/serialized_dataobject";
    protected String implClassname;
    protected HelperContext localCtx;
    protected SDODataObject localDObj;
    protected HelperContext globalCtx;

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

    protected void resetGlobalContext() {
        ((SDOTypeHelper)globalCtx.getTypeHelper()).reset();
        ((SDOXSDHelper)globalCtx.getXSDHelper()).reset();
        ((SDOXMLHelper)globalCtx.getXMLHelper()).reset();
    }

    public void setUp() {
        FileInputStream inStream = null;
        // Clear defined schemas
        super.setUp();
        // Load the schema
        String xsdString = getXSDString(CONTEXT1_DATAOBJECT_XSD_PATH);
        // Define Types
        localCtx = new SDOHelperContext();
        localCtx.getXSDHelper().define(xsdString);
        localDObj = load(CONTEXT1_DATAOBJECT_XML_PATH, localCtx);
        implClassname = localDObj.getType().getInstanceClassName();
        globalCtx = HelperProviderImpl.getDefaultContext();
    }

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

    /**
     * Test should serialize/deserialize successfully/
     */
    public void testResolveWithHelperContextSetInUserMap() {
        //First overwrite the existing context with an empty one
        SDOHelperContext.putHelperContext(Thread.currentThread().getContextClassLoader(), new SDOHelperContext());
        String xsdString = getXSDString(CONTEXT1_DATAOBJECT_XSD_PATH);
        localCtx = new SDOHelperContext("customId");
        localCtx.getXSDHelper().define(xsdString);
        localDObj = load(CONTEXT1_DATAOBJECT_XML_PATH, localCtx);

        SDOHelperContext.putHelperContext(Thread.currentThread().getContextClassLoader(), localCtx);

        serialize(localDObj, FILE_NAME);
        SDODataObject dobj = (SDODataObject) deserialize(FILE_NAME);
        String dobjImplClassName = dobj.getType().getInstanceClassName();
        assertTrue("Expected ["+implClassname+"] but was ["+dobjImplClassName+"]", dobjImplClassName.equals(implClassname));
        SDOHelperContext.removeHelperContext(Thread.currentThread().getContextClassLoader());
    }

    public void testResolveWithLocalHelperContextSetInUserMap() {
        SDOHelperContext.putHelperContext(Thread.currentThread().getContextClassLoader(), localCtx);
        serialize(localDObj, FILE_NAME);
        SDODataObject dobj = (SDODataObject) deserialize(FILE_NAME);
        String dobjImplClassName = dobj.getType().getInstanceClassName();
        assertTrue("Expected ["+implClassname+"] but was ["+dobjImplClassName+"]", dobjImplClassName.equals(implClassname));
        SDOHelperContext.removeHelperContext(Thread.currentThread().getContextClassLoader());
    }

    /**
     * We do not set the loader/helper context pair in the SDOHelperContext
     * user-set map, so we expect an error upon deserialization.  We will
     * get back org.eclipse.persistence.sdo.dataobjects.OpenSequencedTypeImpl,
     * instead of org.example.EmployeeTypeImpl.
     */
    public void testResolveWithoutHelperContextSetInUserMap() {
        serialize(localDObj, FILE_NAME);
        resetGlobalContext();
        DataObject dobj = deserialize(FILE_NAME);
        String dobjImplClassName = dobj.getType().getInstanceClass().getName();
        assertFalse("Expected [org.eclipse.persistence.sdo.dataobjects.OpenSequencedType] but was ["+dobjImplClassName+"]", dobjImplClassName.equals(implClassname));
    }

    public void serialize(DataObject anObject, String filename) {
        FileOutputStream aFileOutputStream = null;
        ObjectOutputStream anObjectInputStream = null;
        try {
            aFileOutputStream = new FileOutputStream(filename);
            anObjectInputStream = new ObjectOutputStream(aFileOutputStream);
            anObjectInputStream.writeObject(anObject);
            anObjectInputStream.flush();
            aFileOutputStream.close();
            anObjectInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            fail("An exception occurred during serialize");
        }
    }

    public DataObject deserialize(String filename) {
        FileInputStream aFileInputStream = null;
        DataObjectInputStream aDataObjectInputStream = null;
        DataObject anObject = null;
        try {
            aFileInputStream = new FileInputStream(filename);
            aDataObjectInputStream = new DataObjectInputStream(aFileInputStream, globalCtx);
            anObject = (DataObject)aDataObjectInputStream.readObject();
            aDataObjectInputStream.close();
            aFileInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            fail("An exception occurred during deserialize");
        }
        return anObject;
    }

    public void testPutGetNamedHelperContextByClassLoader() {
        ClassLoader classLoader = this.getClass().getClassLoader();
        SDOHelperContext controlHelperContext = new SDOHelperContext("testPutGetNamedHelperContextByClassLoader");
        SDOHelperContext.putHelperContext(classLoader, controlHelperContext);
        HelperContext testHelperContext = SDOHelperContext.getHelperContext(controlHelperContext.getIdentifier(), classLoader);
        assertSame(controlHelperContext, testHelperContext);
        SDOHelperContext.removeHelperContext(controlHelperContext.getIdentifier(), classLoader);
    }

}
