/*
 * 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:
// Denise Smith - 2.3
package org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlnametransformer;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jakarta.xml.bind.JAXBContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;

import org.eclipse.persistence.exceptions.JAXBException;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.testing.jaxb.JAXBTestCases;
import org.eclipse.persistence.testing.oxm.OXTestCase;
import org.w3c.dom.Document;

public class NameTransformerExceptionTestCases extends OXTestCase{
    protected final static String XML_RESOURCE = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/xmlnametransformer/nametransformerupper.xml";
    protected DocumentBuilder parser;
    public NameTransformerExceptionTestCases(String name) throws Exception {
        super(name);
    }

    @Override
    public void setUp() throws Exception {
         try {
             DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
             builderFactory.setNamespaceAware(true);
             builderFactory.setIgnoringElementContentWhitespace(true);
             parser = builderFactory.newDocumentBuilder();
         } catch (Exception e) {
             e.printStackTrace();
             fail("An exception occurred during setup");
         }

    }

    public void testExceptionDuringTransform(){
         Type[] types = new Type[1];
         types[0] = Employee.class;
         try{
             JAXBContext jaxbContext = JAXBContextFactory.createContext(types, getPropertiesWithException(), Thread.currentThread().getContextClassLoader());
         } catch (jakarta.xml.bind.JAXBException e) {
//             e.printStackTrace();

        Exception linkedException = (Exception) e.getLinkedException();
        Exception nestedExcpetion = (Exception) e.getCause();
             assertTrue(nestedExcpetion instanceof JAXBException);

             assertEquals(JAXBException.EXCEPTION_DURING_NAME_TRANSFORMATION,((JAXBException)nestedExcpetion).getErrorCode());
             return;
         } catch (Exception e) {
             fail("A JAXBException should have occurred but didn't");
         }
         fail("A JAXBException should have occurred but didn't");
    }

    public void testInvalidNameTransformer(){
        Type[] types = new Type[1];
        types[0] = Employee.class;
        try{
            JAXBContext jaxbContext = JAXBContextFactory.createContext(types, getProperties(), Thread.currentThread().getContextClassLoader());
        } catch (jakarta.xml.bind.JAXBException e) {
            Exception linkedException = (Exception) e.getLinkedException();
            Exception nestedExcpetion = (Exception) e.getCause();
            assertTrue(nestedExcpetion instanceof JAXBException);

            assertEquals(JAXBException.EXCEPTION_WITH_NAME_TRANSFORMER_CLASS,((JAXBException)nestedExcpetion).getErrorCode());
            return;
        } catch (Exception e) {
            fail("A JAXBException should have occurred but didn't");
        }
        fail("A JAXBException should have occurred but didn't");
    }

    protected Map getProperties() {

        Map overrides = new HashMap();
        String overridesString =
        "<?xml version='1.0' encoding='UTF-8'?>" +
        "<xml-bindings xmlns='http://www.eclipse.org/eclipselink/xsds/persistence/oxm' xml-name-transformer='org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlnametransformer.MyNonExistentTransformer'>" +
        "<xml-schema namespace='myuri' />" +
        "<java-types/>" +
        "</xml-bindings>";

        DOMSource src = null;
        try {
            Document doc = parser.parse(new ByteArrayInputStream(overridesString.getBytes()));
            src = new DOMSource(doc.getDocumentElement());
        } catch (Exception e) {
            e.printStackTrace();
            fail("An error occurred during setup");
        }

        overrides.put("org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlnametransformer", src);

        Map props = new HashMap();
        props.put(JAXBContextProperties.OXM_METADATA_SOURCE, overrides);
        return props;
    }

protected Map getPropertiesWithException() throws Exception{

        Map overrides = new HashMap();
        String overridesString =
        "<?xml version='1.0' encoding='UTF-8'?>" +
        "<xml-bindings xmlns='http://www.eclipse.org/eclipselink/xsds/persistence/oxm' xml-name-transformer='org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlnametransformer.TransformerWithException'>" +
        "<xml-schema namespace='myuri' />" +
        "<java-types/>" +
        "</xml-bindings>";

        DOMSource src = null;
        try {
            Document doc = parser.parse(new ByteArrayInputStream(overridesString.getBytes()));
            src = new DOMSource(doc.getDocumentElement());
        } catch (Exception e) {
            e.printStackTrace();
            fail("An error occurred during setup");
        }

        overrides.put("org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlnametransformer", src);

        Map props = new HashMap();
        props.put(JAXBContextProperties.OXM_METADATA_SOURCE, overrides);
        return props;
    }

}
