/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package xmlobject.detailed;

import org.apache.xmlbeans.XmlCalendar;
import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.xmlsoap.schemas.soap.envelope.Detail;
import org.xmlsoap.schemas.soap.envelope.Fault;
import xmlobjecttest.soapfaults.FirstFaultType;

import javax.xml.namespace.QName;
import java.util.ArrayList;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class SoapFaultTest {
    private static final String soapenv = "http://schemas.xmlsoap.org/soap/envelope/";

    /**
     * Regression test for Radar bug #25114
     */
    @Test
    @Disabled
    public void testSetDetail() throws Exception {
        Fault fault = Fault.Factory.newInstance();
        fault.setDetail(Detail.Factory.parse(XmlObject.Factory.parse("<foo/>").newXMLStreamReader()));

        assertEquals("<detail><foo/></detail>", fault.xmlText());
        assertEquals("<xml-fragment><foo/></xml-fragment>", fault.getDetail().xmlText());
    }

    /**
     * Regression test for Radar bug #25119
     */
    @Test
    void testAddNewDetail() throws Exception {
        Fault fault = Fault.Factory.newInstance();

        fault.setFaultcode(new QName(soapenv, "foo"));
        fault.setFaultstring("Undefined");
        fault.addNewDetail().set(
            XmlObject.Factory.parse("<foo/>").changeType(Detail.type));

        String expect =
            "<xml-fragment>" +
            "<faultcode xmlns:soapenv=\"" + soapenv + "\">soapenv:foo</faultcode>" +
            "<faultstring>Undefined</faultstring>" +
            "<detail><foo/></detail>" +
            "</xml-fragment>";
        assertEquals(expect, fault.xmlText());
        assertEquals(new QName(soapenv, "foo"), fault.getFaultcode());
        assertEquals("Undefined", fault.getFaultstring());
        assertEquals("<foo/>", fault.getDetail().xmlText());
    }

    /**
     * Regression test for Radar bug #25409
     */
    @Test
    @Disabled
    public void testSetFaultDetail() throws Exception {
        String soapFault =
            "<soapenv:Fault xmlns:soapenv=\"" + soapenv + "\">" +
            "<faultcode>soapenv:Server</faultcode>" +
            "<faultstring>Undefined</faultstring>" +
            "<detail>" +
            "    <soap:a-string xmlns:soap=\"http://xmlobjecttest/soapfaults\">" +
            "        The First Fault" +
            "    </soap:a-string>" +
            "    <soap:a-int xmlns:soap=\"http://xmlobjecttest/soapfaults\">" +
            "        1" +
            "    </soap:a-int>" +
            "    <soap:a-date xmlns:soap=\"http://xmlobjecttest/soapfaults\">" +
            "       2003-03-28" +
            "    </soap:a-date>" +
            "</detail>" +
            "</soapenv:Fault>";

        Fault faultDoc = Fault.Factory.parse(soapFault);
        XmlOptions opt = new XmlOptions();
        ArrayList<XmlError> errors = new ArrayList<>();
        opt.setErrorListener(errors);
        assertTrue(faultDoc.validate(opt));
        assertEquals(new QName(soapenv, "Server"), faultDoc.getFaultcode());
        assertEquals("Undefined", faultDoc.getFaultstring());


        FirstFaultType firstFault = FirstFaultType.Factory.newInstance();
        System.out.println("firstFault = " + firstFault.xmlText());
        firstFault.set(faultDoc.getDetail());

        assertEquals("The First Fault", firstFault.getAString().trim());
        assertEquals(1, firstFault.getAInt());
        assertEquals(new XmlCalendar("2003-03-28"), firstFault.getADate());
    }
}
