/*
 * 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, 2010 - 2.0.1
package org.eclipse.persistence.testing.jaxb.typemappinginfo.collisions;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.List;

import jakarta.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

import org.eclipse.persistence.jaxb.TypeMappingInfo;
import org.eclipse.persistence.jaxb.TypeMappingInfo.ElementScope;
import org.eclipse.persistence.testing.jaxb.typemappinginfo.TypeMappingInfoTestCases;
import org.eclipse.persistence.testing.jaxb.typemappinginfo.TypeMappingInfoWithJSONTestCases;

public class ConflictingMapsTestCases extends TypeMappingInfoTestCases{

    protected final static String XML_RESOURCE = "org/eclipse/persistence/testing/jaxb/typemappinginfo/collisions/conflictingMaps.xml";

    public Map<Object, Object> testField1;
    public Map<Object, String> testField2;
    public Map<String, Object> testField3;
    public Map<Integer, Integer> testField4;
    public Map<Integer, Integer> testField5;

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

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

    protected TypeMappingInfo[] getTypeMappingInfos()throws Exception {
        if(typeMappingInfos == null) {
            typeMappingInfos = new TypeMappingInfo[7];

            TypeMappingInfo tmi = new TypeMappingInfo();
            tmi.setXmlTagName(new QName("","testTagName1"));
            tmi.setElementScope(ElementScope.Global);
            tmi.setType(getClass().getField("testField1").getGenericType());
            typeMappingInfos[0] = tmi;

            TypeMappingInfo tmi2 = new TypeMappingInfo();
            tmi2.setXmlTagName(new QName("","testTagName2"));
            tmi2.setElementScope(ElementScope.Global);
            tmi2.setType(getClass().getField("testField2").getGenericType());
            typeMappingInfos[1] = tmi2;

            TypeMappingInfo tmi3 = new TypeMappingInfo();
            tmi3.setXmlTagName(new QName("","testTagName3"));
            tmi3.setElementScope(ElementScope.Global);
            tmi3.setType(getClass().getField("testField3").getGenericType());
            typeMappingInfos[2] = tmi3;

            TypeMappingInfo tmi4 = new TypeMappingInfo();
            tmi4.setXmlTagName(new QName("","testTagName4"));
            tmi4.setElementScope(ElementScope.Global);
            tmi4.setType(getClass().getField("testField4").getGenericType());
            typeMappingInfos[3] = tmi4;

            TypeMappingInfo tmi5 = new TypeMappingInfo();
            tmi5.setXmlTagName(new QName("","testTagName5"));
            tmi5.setElementScope(ElementScope.Global);
            tmi5.setType(getClass().getField("testField4").getGenericType());
            typeMappingInfos[4] = tmi5;

            TypeMappingInfo tmi6 = new TypeMappingInfo();
            tmi6.setXmlTagName(new QName("","testTagName6"));
            tmi6.setElementScope(ElementScope.Global);
            tmi6.setType(Map.class);
            typeMappingInfos[5] = tmi6;

            TypeMappingInfo tmi7 = new TypeMappingInfo();
            tmi7.setXmlTagName(new QName("","testTagName7"));
            tmi7.setElementScope(ElementScope.Global);
            tmi7.setType(HashMap.class);
            typeMappingInfos[6] = tmi7;
        }
        return typeMappingInfos;
    }


    @Override
    protected Object getControlObject() {

        Map<Object, Object> theMap = new HashMap<Object, Object>();

        QName qname = new QName("", "testTagName");
        JAXBElement jaxbElement = new JAXBElement(qname, Object.class, null);
        theMap.put("abc", 123);
        jaxbElement.setValue(theMap);

        return jaxbElement;
    }

    @Override
    public Map<String, InputStream> getControlSchemaFiles(){
        InputStream instream = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/jaxb/typemappinginfo/collisions/conflictingMaps.xsd");

        Map<String, InputStream> controlSchema = new HashMap<String, InputStream>();
        controlSchema.put("", instream);

        return controlSchema;
    }

    protected String getNoXsiTypeControlResourceName() {
        return XML_RESOURCE;
    }

    public void testDescriptorsSize(){
        List descriptors = ((org.eclipse.persistence.jaxb.JAXBContext)jaxbContext).getXMLContext().getSession(0).getProject().getOrderedDescriptors();
        assertEquals(10, descriptors.size());
    }
}
