/*
 * 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.jaxb.xmlmarshaller;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.MarshalException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.PropertyException;
import jakarta.xml.bind.util.JAXBResult;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.persistence.testing.oxm.OXTestCase;

public class MarshallerEncodingTest extends OXTestCase {
    private final static int CONTROL_EMPLOYEE_ID = 123;
    private final static String CONTROL_EMAIL_ADDRESS_USER_ID = "jane.doe";
    private final static String CONTROL_EMAIL_ADDRESS_DOMAIN = "example.com";
    private final static String XML_RESOURCE = "org/eclipse/persistence/testing/oxm/jaxb/Employee.xml";
    private Object controlObject;
    private DocumentBuilder parser;
    private String encoding;
    private String controlString;
    private String originalEncoding;
    private Boolean originalFormatting;
    private Marshaller marshaller;

    private String contextPath;

    public MarshallerEncodingTest(String name, String encoding, String controlString) {
        super(name);
        this.encoding = encoding;
        this.controlString = controlString;
    }

    @Override
    public void setUp() throws Exception {
        contextPath = System.getProperty("jaxb.test.contextpath", JAXBSAXTestSuite.CONTEXT_PATH);

        JAXBContext jaxbContext = JAXBContext.newInstance(contextPath, getClass().getClassLoader());
        marshaller = jaxbContext.createMarshaller();
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        documentBuilderFactory.setIgnoringElementContentWhitespace(true);
        parser = documentBuilderFactory.newDocumentBuilder();

        originalEncoding = (String)marshaller.getProperty(Marshaller.JAXB_ENCODING);
        originalFormatting = (Boolean)marshaller.getProperty(Marshaller.JAXB_FORMATTED_OUTPUT);
        marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.valueOf(false));
        controlObject = setupControlObject();

    }

    protected Employee setupControlObject() {
        Employee employee = new Employee();
        employee.setID(CONTROL_EMPLOYEE_ID);

        employee.setName("Bob\u0A00Jones");

        Phone p = new Phone();
        p.setNumber("123456789");
        employee.setPhone(p);

        return employee;
    }

    public void testXMLHeader() throws Exception {

        /*
        // A JAXP version of this test is required.
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        marshaller.marshal(controlObject, outStream);

        String stringToParse = outStream.toString(encoding);
        StringReader reader = new StringReader(stringToParse);
        parser.parse(reader);

        log(parser.getDocument());
        assertEquals(encoding, parser.getDocument().getEncoding());
        */
    }

    public void testXMLEncoding() throws Exception {
        log("\nEncoding is: " + encoding);

        byte[] controlBytes = controlString.getBytes(encoding);
        log("\nCONTROL_STRING:" + new String(controlBytes, encoding));
        marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);

        ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
        marshaller.marshal(controlObject, byteOutStream);
        log("TESTING_STRING:" + byteOutStream.toString());

        byte[] testBytes = byteOutStream.toByteArray();

        log("CONTROL_BYTES");
        log(controlBytes);
        log("TESTING_BYTES");
        log(testBytes);

        assertTrue(compareByteArrays(testBytes, controlBytes));
    }

    public void testXMLEncodingWriter() throws Exception {
        log("towriter ###########");
        log("\nEncoding is: " + encoding);

        byte[] controlBytes = controlString.getBytes(encoding);
        log("\nCONTROL_STRING:" + new String(controlBytes, encoding));
        marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);

        StringWriter writer = new StringWriter();
        marshaller.marshal(controlObject, writer);
        log("TESTING_STRING:" + writer.toString());
        byte[] testBytes = writer.toString().getBytes();

        log("CONTROL_BYTES");
        log(controlBytes);
        log("TESTING_BYTES");
        log(testBytes);

        assertTrue(compareByteArrays(testBytes, controlBytes));
    }

    public void testXMLEncodingFileOutputStream() throws Exception {
        log("\ntowriter ###########");
        log("\nEncoding is: " + encoding);

        byte[] controlBytes = controlString.getBytes();
        log("\nCONTROL_STRING:" + new String(controlBytes));
        marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
        String filename = "FileOutStream" + encoding + ".xml";
        OutputStreamWriter outStream = new OutputStreamWriter(new FileOutputStream(filename));

        marshaller.marshal(controlObject, outStream);
        log("TESTING_STRING:" + outStream.toString());

        FileInputStream inStream = new FileInputStream(filename);
        byte[] testBytes = new byte[inStream.available()];
        inStream.read(testBytes);

        log("CONTROL_BYTES");
        log(controlBytes);
        log("TESTING_BYTES");
        log(testBytes);

        if (!useLogging) {
            java.io.File f = new java.io.File("filename");
            if (f.exists()) {
                f.delete();
            }
        }

        assertTrue(compareByteArrays(testBytes, controlBytes));
    }

    public void testXMLEncodingFileOutputStreamEnc() throws Exception {
        log("\ntowriter ###########");
        log("\nEncoding is: " + encoding);

        byte[] controlBytes = controlString.getBytes(encoding);
        log("\nCONTROL_STRING:" + new String(controlBytes, encoding));
        marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);

        String filename = "FileOutStreamEnc" + encoding + ".xml";
        OutputStreamWriter outStream = new OutputStreamWriter(new FileOutputStream(filename), encoding);

        marshaller.marshal(controlObject, outStream);

        FileInputStream inStream = new FileInputStream(filename);
        byte[] testBytes = new byte[inStream.available()];
        inStream.read(testBytes);

        log("CONTROL_BYTES");
        log(controlBytes);
        log("TESTING_BYTES");
        log(testBytes);

        if (!useLogging) {
            java.io.File f = new java.io.File("filename");
            if (f.exists()) {
                f.delete();
            }
        }

        assertTrue(compareByteArrays(testBytes, controlBytes));
    }

    public void testXMLEncodingFileWriter() throws Exception {
        log("\ntowriter ###########");
        log("\nEncoding is: " + encoding);

        byte[] controlBytes = controlString.getBytes();
        log("\nCONTROL_STRING:" + new String(controlBytes, encoding));
        marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);

        String filename = "FileWriter" + encoding + ".xml";
        FileWriter writer = new FileWriter(filename);

        marshaller.marshal(controlObject, writer);
        FileInputStream inStream = new FileInputStream(filename);
        byte[] testBytes = new byte[inStream.available()];
        inStream.read(testBytes);

        log("CONTROL_BYTES");
        log(controlBytes);
        log("TESTING_BYTES");
        log(testBytes);

        if (!useLogging) {
            java.io.File f = new java.io.File("filename");
            if (f.exists()) {
                f.delete();
            }
        }

        assertTrue(compareByteArrays(testBytes, controlBytes));
    }

    public void testInvalidEncoding() throws Exception {
        marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);

        ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
        try {
            marshaller.marshal(controlObject, byteOutStream);
        } catch (MarshalException e) {
            assertTrue(true);
            return;
        } catch (Exception e) {
            fail("Unexpected exception. A MarshalException should have been thrown but was not");
            return;
        }
        fail("A MarshalException should have been thrown but was not");
    }

    @Override
    public void tearDown() throws PropertyException {
        marshaller.setProperty(Marshaller.JAXB_ENCODING, originalEncoding);
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, originalFormatting);
    }

    private boolean compareByteArrays(byte[] first, byte[] second) {
        if (first.length != second.length) {
            return false;
        }

        for (int i = 0; i < first.length; i++) {
            if (first[i] != second[i]) {
                return false;
            }
        }
        return true;
    }

}
