/*
 * 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 - October 2012
package org.eclipse.persistence.testing.jaxb.unmarshaller.autodetect;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.UnmarshallerProperties;
import org.eclipse.persistence.oxm.MediaType;
import org.eclipse.persistence.testing.jaxb.JAXBTestCases;
import org.eclipse.persistence.testing.jaxb.JAXBWithJSONTestCases;
import org.eclipse.persistence.testing.oxm.mappings.choicecollection.ref.Address;
import org.eclipse.persistence.testing.oxm.mappings.choicecollection.ref.Employee;
import org.eclipse.persistence.testing.oxm.mappings.choicecollection.ref.PhoneNumber;
import org.eclipse.persistence.testing.oxm.mappings.choicecollection.ref.Root;

public class AutoDetectMediaTypeTestCases extends JAXBWithJSONTestCases {
    private final static String XML_RESOURCE = "org/eclipse/persistence/testing/jaxb/unmarshaller/autodetect/employee-collection.xml";
    private final static String JSON_RESOURCE = "org/eclipse/persistence/testing/jaxb/unmarshaller/autodetect/employee-collection.json";

    public AutoDetectMediaTypeTestCases(String name) throws Exception {
        super(name);
        setControlDocument(XML_RESOURCE);
        setControlJSON(JSON_RESOURCE);
        Class[] classes = new Class[1];
        classes[0] = TestObjectFactory.class;
        setClasses(classes);
        jaxbUnmarshaller.setProperty(UnmarshallerProperties.AUTO_DETECT_MEDIA_TYPE, true);
    }

    @Override
    protected Object getControlObject() {
        EmployeeCollection employee = new EmployeeCollection();
        ArrayList choices = new ArrayList();
        choices.add(new JAXBElement(new QName("integer-root"), Integer.class, Integer.valueOf(21)));
        choices.add(new JAXBElement(new QName("root"), String.class, "Value1"));
        EmployeeCollection nestedEmployee = new EmployeeCollection();
        nestedEmployee.refs = new ArrayList();
        nestedEmployee.refs.add(new JAXBElement(new QName("integer-root"), Integer.class, Integer.valueOf(29)));
        choices.add(nestedEmployee);
        choices.add(new JAXBElement(new QName("root"), String.class, "Value2"));
        employee.refs = choices;
        return employee;
     }


    @Override
    protected Object getJSONReadControlObject(){
        //same as getReadControl Except order is different
        EmployeeCollection employee = new EmployeeCollection();
        ArrayList choices = new ArrayList();
        choices.add(new JAXBElement(new QName("integer-root"), Integer.class, Integer.valueOf(21)));
        choices.add(new JAXBElement(new QName("root"), String.class, "Value1"));
        choices.add(new JAXBElement(new QName("root"), String.class, "Value2"));

        EmployeeCollection nestedEmployee = new EmployeeCollection();
        nestedEmployee.refs = new ArrayList();
        nestedEmployee.refs.add(new JAXBElement(new QName("integer-root"), Integer.class, Integer.valueOf(29)));
        choices.add(nestedEmployee);
        employee.refs = choices;
        return employee;
    }

    @Override
    public MediaType getXMLUnmarshalMediaType(){
          return MediaType.APPLICATION_JSON;
    }

    @Override
    public MediaType getJSONUnmarshalMediaType(){
       return MediaType.APPLICATION_XML;
    }

    public void testUnmarshalStreamSourceURLJSON() throws Exception{
        File file = new File(ClassLoader.getSystemResource(JSON_RESOURCE).getFile());
        String systemId = file.toURI().toURL().toExternalForm();

        StreamSource ss = new StreamSource(systemId);
        Object testObject = jaxbUnmarshaller.unmarshal(ss);
        jsonToObjectTest(testObject);

    }

    public void testUnmarshalStreamSourceURLXML() throws Exception{
        File file = new File(ClassLoader.getSystemResource(XML_RESOURCE).getFile());
        String systemId = file.toURI().toURL().toExternalForm();

        StreamSource ss = new StreamSource(systemId);
        Object testObject = jaxbUnmarshaller.unmarshal(ss);
        xmlToObjectTest(testObject);

    }

    public void testUnmarshalStreamSourceURLJSONWithClass() throws Exception{
        File file = new File(ClassLoader.getSystemResource(JSON_RESOURCE).getFile());
        String systemId = file.toURI().toURL().toExternalForm();

        StreamSource ss = new StreamSource(systemId);
        JAXBElement jbe = jaxbUnmarshaller.unmarshal(ss, EmployeeCollection.class);

        jsonToObjectTest(jbe.getValue());

    }

    public void testUnmarshalStreamSourceURLXMLWithClass() throws Exception{
        File file = new File(ClassLoader.getSystemResource(XML_RESOURCE).getFile());
        String systemId = file.toURI().toURL().toExternalForm();

        StreamSource ss = new StreamSource(systemId);
        JAXBElement jbe  = jaxbUnmarshaller.unmarshal(ss, EmployeeCollection.class);
        xmlToObjectTest(jbe.getValue());

    }

    public void testUnmarshalStreamSourceNoProtocolJSONWithClass() throws Exception{
        File file = new File(ClassLoader.getSystemResource(JSON_RESOURCE).getFile());
        String systemId = file.getAbsolutePath();

        StreamSource ss = new StreamSource(systemId);
        JAXBElement jbe = jaxbUnmarshaller.unmarshal(ss, EmployeeCollection.class);

        jsonToObjectTest(jbe.getValue());

    }

    public void testUnmarshalStreamSourceNoProtocolXMLWithClass() throws Exception{
        File file = new File(ClassLoader.getSystemResource(XML_RESOURCE).getFile());
        String systemId = file.getAbsolutePath();

        StreamSource ss = new StreamSource(systemId);
        JAXBElement jbe  = jaxbUnmarshaller.unmarshal(ss, EmployeeCollection.class);
        xmlToObjectTest(jbe.getValue());

    }

    public void testJSONToObjectFromXMLStreamReader() throws Exception {
        if(null != XML_INPUT_FACTORY) {
            InputStream instream = ClassLoader.getSystemResourceAsStream(XML_RESOURCE);
            XMLStreamReader xmlStreamReader = XML_INPUT_FACTORY.createXMLStreamReader(instream);
            jaxbUnmarshaller.setProperty(UnmarshallerProperties.AUTO_DETECT_MEDIA_TYPE, true);
            jaxbUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);

            Object testObject = jaxbUnmarshaller.unmarshal(xmlStreamReader);
            instream.close();
            xmlToObjectTest(testObject);
        }
    }
}
