/*
 * 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:
// 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();
    }

    @Override
    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);
    }

}
