/*
 * 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 -  January 2014
package org.eclipse.persistence.testing.jaxb.typemappinginfo;

import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import jakarta.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.TypeMappingInfo;
import org.eclipse.persistence.jaxb.TypeMappingInfo.ElementScope;
import org.eclipse.persistence.testing.jaxb.typemappinginfo.pkg2.Thing;
import org.eclipse.persistence.testing.jaxb.typemappinginfo.pkg3.OtherThing;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

public class DefaultTargetNamespaceConflictTestCases extends TypeMappingInfoWithJSONTestCases{

    protected final static String XML_RESOURCE = "org/eclipse/persistence/testing/jaxb/typemappinginfo/conflict/otherthing.xml";
    protected final static String JSON_RESOURCE = "org/eclipse/persistence/testing/jaxb/typemappinginfo/conflict/otherthing.json";

    public DefaultTargetNamespaceConflictTestCases(String name) throws Exception {
        super(name);
        init();
    }

    public void init() throws Exception {
        setControlDocument(XML_RESOURCE);
        setControlJSON(JSON_RESOURCE);
        setTypeMappingInfos(getTypeMappingInfos());
    }

    @Override
    public TypeMappingInfo getTypeMappingInfo(){
          return getTypeMappingInfos()[0];
    }

    protected TypeMappingInfo[] getTypeMappingInfos() {
        if(typeMappingInfos == null) {
            typeMappingInfos = new TypeMappingInfo[2];

            TypeMappingInfo tmi2 = new TypeMappingInfo();
            tmi2.setType(OtherThing.class);
            typeMappingInfos[0] = tmi2;

            TypeMappingInfo tmi = new TypeMappingInfo();
            tmi.setType(Thing.class);
            typeMappingInfos[1] = tmi;
        }
        return typeMappingInfos;
    }

    @Override
    protected Object getControlObject() {
        OtherThing otherThing = new OtherThing();
        otherThing.someProperty = 10;
        JAXBElement<OtherThing> jbe = new JAXBElement<OtherThing>(new QName("root"), OtherThing.class, otherThing);

        return jbe;

    }

    public void testCorrectNamespace() throws Exception{
        OtherThing otherThing = new OtherThing();
        otherThing.someProperty = 10;
        StringWriter sw = new StringWriter();

        jaxbMarshaller.marshal(otherThing, sw);

        InputSource is = new InputSource(new StringReader(sw.toString()));
        Node doc = parser.parse(is);
        assertNotNull(doc);
        assertTrue(doc instanceof Document);
        Element root = ((Document)doc).getDocumentElement();
        assertEquals("namespace1",root.getNamespaceURI());
    }


    @Override
    protected Map getProperties() {
        HashMap props = new HashMap();
        props.put(JAXBContextFactory.DEFAULT_TARGET_NAMESPACE_KEY, "namespace1");

        return props;
    }

    @Override
    public Map<String, InputStream> getControlSchemaFiles() {
        InputStream instream = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/jaxb/typemappinginfo/conflict/schema.xsd");
        Map<String, InputStream> controlSchema = new HashMap<String, InputStream>();
        controlSchema.put("namespace1", instream);
        return controlSchema;
    }
}

