/*
 * Copyright (c) 2015, 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:
//     Martin Vojtek - initial version 2.6.0
package org.eclipse.persistence.testing.jaxb.listofobjects.externalizedmetadata;

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

import jakarta.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;

import org.eclipse.persistence.internal.jaxb.JaxbClassLoader;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.testing.jaxb.listofobjects.JAXBListOfObjectsTestCases;
import org.w3c.dom.Document;

/**
 * Tests marshal/unmarshal of xml without xsi type.
 *
 * @author Martin Vojtek
 *
 */
public class JAXBTypedListNoXsiTypeTestCases  extends JAXBListOfObjectsTestCases {
    protected final static String XML_RESOURCE = "org/eclipse/persistence/testing/jaxb/listofobjects/externalizedmetadata/typedlist_noxsi.xml";
    protected final static String XML_RESOURCE_NO_XSI_TYPE = "org/eclipse/persistence/testing/jaxb/listofobjects/externalizedmetadata/typedlistNoXsiType.xml";

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

    @Override
    protected Type getTypeToUnmarshalTo() throws Exception {
        return Company.class;
    }

    public void init() throws Exception {
        setControlDocument(XML_RESOURCE);
        setWriteControlDocument(XML_RESOURCE_NO_XSI_TYPE);
        Class[] classes = new Class[1];
        classes[0] = Company.class;

        setClasses(classes);
    }

    @Override
    protected Map getProperties() {
        String pkg = "org.eclipse.persistence.testing.jaxb.listofobjects.externalizedmetadata";
        HashMap<String, Source> overrides = new HashMap<String, Source>();
        overrides.put(pkg, generateXmlSchemaOxm());
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, overrides);
        return properties;
    }

    private Source generateXmlSchemaOxm() {
        String oxm =
            "<xml-bindings xmlns='http://www.eclipse.org/eclipselink/xsds/persistence/oxm'>" +
               "<java-types>" +
                  "<java-type name='org.eclipse.persistence.testing.jaxb.listofobjects.externalizedmetadata.Company'>"+
                      "<java-attributes>" +
                          "<xml-element java-attribute='departments' name='departments' type='java.lang.Integer'/>" +
                          "<xml-element java-attribute='departmentIdToName' name='departmentIdToName'>" +
                             "<xml-map>" +
                                 "<key type='java.lang.Integer'/>" +
                                 "<value type='java.lang.String'/>" +
                             "</xml-map>" +
                          "</xml-element>" +
                          "<xml-element java-attribute='intObjectMap' name='int-to-object'>" +
                             "<xml-map>" +
                                 "<key type='java.lang.Integer'/>" +
                             "</xml-map>" +
                          "</xml-element>"+
                          "<xml-element java-attribute='objectStringMap' name='object-to-string'>" +
                             "<xml-map>" +
                                 "<value type='java.lang.String'/>" +
                             "</xml-map>" +
                          "</xml-element>" +
                          "<xml-element java-attribute='objectIntMap' name='object-to-int' type='java.lang.String'>" +
                             "<xml-map>" +
                                 "<value type='java.lang.Integer'/>" +
                             "</xml-map>" +
                          "</xml-element>" +
                   "</java-attributes>" +
               "</java-type>" +
              "</java-types>" +
           "</xml-bindings>";

        try{
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            docBuilderFactory.setNamespaceAware(true);
            Document doc = docBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(oxm.getBytes()));
            return new DOMSource(doc.getDocumentElement());
        }catch (Exception e){
            e.printStackTrace();
            fail("An error occurred during getProperties");
        }
        return null;
    }

    @Override
    protected Object getControlObject() {
        Company company = new Company();
        List depts = new ArrayList();
        depts.add(1);
        depts.add(2);
        depts.add(3);
        company.setDepartments(depts);

        QName qname = new QName("examplenamespace", "root");
        JAXBElement jaxbElement = new JAXBElement(qname, Object.class ,null);
        jaxbElement.setValue(company);

        return jaxbElement;

    }

    @Override
    public List< InputStream> getControlSchemaFiles(){
        InputStream instream = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/jaxb/listofobjects/externalizedmetadata/typedlist.xsd");

        List<InputStream> controlSchema = new ArrayList<InputStream>();
        controlSchema.add(instream);
        return controlSchema;
    }

    @Override
    protected String getNoXsiTypeControlResourceName() {
        return XML_RESOURCE_NO_XSI_TYPE;
    }

    @Override
    public void testJSONUnmarshalFromJsonStructureSource() throws Exception {
    }

    @Override
    public void testJSONMarshalToBuilderResult() throws Exception {
    }

    @Override
    public void testJSONMarshalToGeneratorResult() throws Exception {
    }

    @Override
    public void testJSONMarshalToOutputStream() throws Exception {
    }

    @Override
    public void testJSONMarshalToOutputStream_FORMATTED() throws Exception {
    }

    @Override
    public void testJSONMarshalToStringWriter() throws Exception {
    }

    @Override
    public void testJSONMarshalToStringWriter_FORMATTED() throws Exception {
    }

    @Override
    public void testJSONUnmarshalFromInputSource() throws Exception {
    }

    @Override
    public void testJSONUnmarshalFromInputStream() throws Exception {
    }

    @Override
    public void testJsonUnmarshalFromJsonParserSource() throws Exception {
    }

    @Override
    public void testJSONUnmarshalFromReader() throws Exception {
    }

    @Override
    public void testJSONUnmarshalFromSource() throws Exception {
    }

    @Override
    public void testJSONUnmarshalFromURL() throws Exception {
    }

    @Override
    public void testUnmarshalAutoDetect() throws Exception {
    }
}
