/**
 * Copyright (c) 2016-2024 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.binding.soap.util;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.logging.Logger;

import javax.jbi.messaging.Fault;
import javax.jbi.messaging.NormalizedMessage;
import javax.jbi.messaging.NormalizedMessageProperties;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.soap.SOAPBody;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPProcessingException;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.junit.Test;
import org.ow2.petals.jbi.xml.BytesSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Some tests mainly around the workaround introduced for PETALSBCSOAP-192
 * 
 * @author vnoel
 *
 */
public class MarshallerTest {

    private static final Logger LOG = Logger.getLogger(MarshallerTest.class.getName());

    private DOMSource createDocumentSource(boolean usingNamespaceUawareAttribute) throws ParserConfigurationException {
        Document outputDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

        Element rootElement = outputDocument.createElementNS("http://test/", "tns:executeJobResponse");
        outputDocument.appendChild(rootElement);
        if (usingNamespaceUawareAttribute) {
            rootElement.setAttribute("xmlns:xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
        } else {
            rootElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:xsi",
                    XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
        }

        return new DOMSource(outputDocument);
    }

    @Test
    public void checkcreateSOAPBody_FromDocumentSource_UsingNamespaceUnawareAttribute() throws SOAPProcessingException, ParserConfigurationException {
        final SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
        final SOAPBody soapBody = Marshaller.createSOAPBody(factory, factory.createSOAPEnvelope(),
                createDocumentSource(true), false, Logger.getAnonymousLogger());
        assertNotNull(soapBody);
    }

    @Test
    public void checkcreateSOAPBody_FromDocumentSource_UsingNamespaceAwareAttribute() throws SOAPProcessingException, ParserConfigurationException {
        final SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
        final SOAPBody soapBody = Marshaller.createSOAPBody(factory, factory.createSOAPEnvelope(),
                createDocumentSource(false), false, Logger.getAnonymousLogger());
        assertNotNull(soapBody);
    }

    /**
     * Create a SOAP Fault associated to a business error extracted from a JBI Fault.
     */
    @Test
    public void createSOAPEnvelopeForBusinessError() {
        final SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
        final QName ROOT_ELT = new QName("http://my-namespace", "my-fault");

        final NormalizedMessage nm = EasyMock.createMock(Fault.class);
        EasyMock.expect(nm.getContent()).andAnswer(new IAnswer<Source>() {

            @Override
            public Source answer() throws Throwable {
                return new BytesSource(
                        String.format(
                                "<%s xmlns=\"%s\" xmlns:tns=\"http://my-namespace/sub-namespace/\"><tns:my-fault-info>my-fault-info</tns:my-fault-info></%s>",
                                ROOT_ELT.getLocalPart(), ROOT_ELT.getNamespaceURI(), ROOT_ELT.getLocalPart())
                                .getBytes());
            }
        }).anyTimes();
        EasyMock.expect(nm.getProperty(NormalizedMessageProperties.PROTOCOL_HEADERS)).andReturn(null).anyTimes();
        EasyMock.replay(nm);

        final SOAPEnvelope env = Marshaller.createSOAPEnvelope(factory, nm, LOG);
        assertNotNull(env);
        assertNotNull(env.getBody());
        assertNotNull(env.getBody().getFault());
        assertNotNull(env.getBody().getFault().getDetail());
        assertEquals(ROOT_ELT, env.getBody().getFault().getDetail().getFirstElement().getQName());
    }
}
