/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 org.apache.axis2.saaj;

import junit.framework.Assert;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import jakarta.xml.soap.MessageFactory;
import jakarta.xml.soap.Name;
import jakarta.xml.soap.Node;
import jakarta.xml.soap.SOAPBody;
import jakarta.xml.soap.SOAPBodyElement;
import jakarta.xml.soap.SOAPConstants;
import jakarta.xml.soap.SOAPElement;
import jakarta.xml.soap.SOAPEnvelope;
import jakarta.xml.soap.SOAPFault;
import jakarta.xml.soap.SOAPHeader;
import jakarta.xml.soap.SOAPMessage;
import jakarta.xml.soap.SOAPPart;
import jakarta.xml.soap.Text;
import java.util.Iterator;

@RunWith(SAAJTestRunner.class)
public class SOAPBodyTest extends Assert {

    /**
     * Method suite
     *                                                         
     * @return
     */
    /*  public static Test suite() {
          return new TestSuite(test.message.TestSOAPBody.class);
      }
    */

    /**
     * Method testSoapBodyBUG
     *
     * @throws Exception
     */
    @Validated @Test
    public void testSoapBody() throws Exception {

        MessageFactory fact = MessageFactory.newInstance();
        SOAPMessage message = fact.createMessage();
        SOAPPart soapPart = message.getSOAPPart();
        SOAPEnvelope env = soapPart.getEnvelope();
        SOAPHeader header = env.getHeader();
        Name hns = env.createName("Hello",
                                  "shw",
                                  "http://www.jcommerce.net/soap/ns/SOAPHelloWorld");
        SOAPElement headElmnt = header.addHeaderElement(hns);
        Name hns1 = env.createName("Myname",
                                   "shw",
                                   "http://www.jcommerce.net/soap/ns/SOAPHelloWorld");
        SOAPElement myName = headElmnt.addChildElement(hns1);
        myName.addTextNode("Tony");
        Name ns = env.createName("Address",
                                 "shw",
                                 "http://www.jcommerce.net/soap/ns/SOAPHelloWorld");
        SOAPBody body = env.getBody();
        SOAPElement bodyElmnt = body.addBodyElement(ns);
        Name ns1 = env.createName("City",
                                  "shw",
                                  "http://www.jcommerce.net/soap/ns/SOAPHelloWorld");
        SOAPElement city = bodyElmnt.addChildElement(ns1);
        city.addTextNode("GENT");

        SOAPElement city2 = body.addChildElement(ns1);
        assertTrue(city2 instanceof SOAPBodyElement);
        city2.addTextNode("CIT2");

        Iterator it = body.getChildElements();
        int count = 0;

        while (it.hasNext()) {
            Object o = it.next();
            assertTrue(o instanceof SOAPBodyElement);
            SOAPBodyElement bodyElement = (SOAPBodyElement)o;
            assertEquals("http://www.jcommerce.net/soap/ns/SOAPHelloWorld",
                         bodyElement.getNamespaceURI());
            assertEquals("shw", bodyElement.getPrefix());
            assertTrue(bodyElement.getLocalName().equals("City") ||
                    bodyElement.getLocalName().equals("Address"));
            count++;
        }
        assertEquals(2, count);
    }

    public void _testAddDocument() {
        try {
            Document document = null;
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);

            DocumentBuilder builder = factory.newDocumentBuilder();
            document = builder.parse(TestUtils.getTestFileURI("soap-body.xml"));
            MessageFactory fact = MessageFactory.newInstance();
            SOAPMessage message = fact.createMessage();

            message.getSOAPHeader().detachNode();
            // assertNull(message.getSOAPHeader());    
            // TODO:this fails. Header is always being created if it doesnt exist in DOOM

            SOAPBody soapBody = message.getSOAPBody();
            soapBody.addDocument(document);
            message.saveChanges();

            // Get contents using SAAJ APIs
            Iterator iter1 = soapBody.getChildElements();
            getContents(iter1, "");
        } catch (Exception e) {
            e.printStackTrace();
            fail("Unexpected Exception : " + e);
        }
    }

    private void getContents(Iterator iterator, String indent) {
        while (iterator.hasNext()) {
            Node node = (Node)iterator.next();
            SOAPElement element = null;
            Text text = null;

            if (node instanceof SOAPElement) {
                element = (SOAPElement)node;
                Name name = element.getElementName();
                Iterator attrs = element.getAllAttributes();

                /*
                while (attrs.hasNext()) {
                    Name attrName = (Name) attrs.next();
                    System.out.println(indent + " Attribute name is " +
                                       attrName.getQualifiedName());
                    System.out.println(indent + " Attribute value is " +
                                       element.getAttributeValue(attrName));
                }
                */

                Iterator iter2 = element.getChildElements();
                getContents(iter2, indent + " ");
            } else {
                text = (Text)node;
                assertNotNull(text);
            }
        }
    }

    @Validated @Test
    public void testExtractContentAsDocument() throws Exception {
        MessageFactory fact = MessageFactory.newInstance();
        SOAPMessage message = fact.createMessage();
        SOAPBody soapBody = message.getSOAPBody();

        QName qname1 = new QName("http://wombat.ztrade.com",
                                 "GetLastTradePrice", "ztrade");
        SOAPElement child1 = soapBody.addChildElement(qname1);
        Document document = soapBody.extractContentAsDocument();

        assertNotNull(document);
        assertTrue(document instanceof Document);
        Element element = document.getDocumentElement();
        String elementName = element.getTagName();

        //Retreive the children of the SOAPBody (should be none)
        Iterator childElements = soapBody.getChildElements();
        int childCount = 0;
        while (childElements.hasNext()) {
            Object object = childElements.next();
            childCount++;
        }
        assertEquals(childCount, 0);
    }

    /*
     * For SOAP 1.1 message 
     */
    @Validated @Test
    public void testAddAttribute() {
        try {
            MessageFactory fact = MessageFactory.newInstance();
            SOAPMessage message = fact.createMessage();
            SOAPBody soapBody = message.getSOAPBody();
            QName qname = new QName("http://test.apache.org/", "Child1", "ch");
            String value = "MyValue1";
            soapBody.addAttribute(qname, value);
            message.saveChanges();

        } catch (Exception e) {
            fail("Unexpected Exception : " + e);
        }
    }

    /*
     * For SOAP 1.2 message 
     */
    @Validated @Test
    public void testAddAttribute2() {
        try {
            MessageFactory fact = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
            SOAPMessage message = fact.createMessage();
            SOAPBody soapBody = message.getSOAPBody();
            QName qname = new QName("http://test.apache.org/", "Child1", "ch");
            String value = "MyValue1";
            soapBody.addAttribute(qname, value);
            message.saveChanges();
        } catch (Exception e) {
            fail("Unexpected Exception : " + e);
        }
    }

    /*
    * For SOAP 1.2 message
    */
    @Validated @Test
    public void testAddFault() {
        try {
            MessageFactory fact = MessageFactory.newInstance();
            SOAPMessage message = fact.createMessage();
            SOAPPart soapPart = message.getSOAPPart();
            SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
            SOAPBody soapBody = soapEnvelope.getBody();

            QName qname = new QName("http://test.apache.org/", "Child1", "ch");
            String value = "MyFault";
            SOAPFault soapFault = soapBody.addFault(qname, value);
            message.saveChanges();
            assertNotNull(soapFault);
            assertTrue(soapFault instanceof SOAPFault);
        } catch (Exception e) {
            fail("Unexpected Exception : " + e);
        }
    }

    @Validated @Test
    public void testAppendChild() throws Exception {
        MessageFactory fact = MessageFactory.newInstance();
        SOAPMessage message = fact.createMessage();
        SOAPBody soapBody = message.getSOAPBody();
        
        assertEquals(0, soapBody.getChildNodes().getLength());
        assertFalse(soapBody.getChildElements().hasNext());
                      
        Document doc = soapBody.getOwnerDocument();        
        String namespace = "http://example.com";
        String localName = "GetLastTradePrice";
        Element getLastTradePrice = doc.createElementNS(namespace, localName);        
        Element symbol = doc.createElement("symbol");
        symbol.setAttribute("foo", "bar");
        getLastTradePrice.appendChild(symbol);
        org.w3c.dom.Text def = doc.createTextNode("DEF");
        symbol.appendChild(def);
                        
        soapBody.appendChild(getLastTradePrice);
        
        assertEquals(1, soapBody.getChildNodes().getLength());
        Iterator iter = soapBody.getChildElements();
        assertTrue(iter.hasNext()); 
        Object obj = iter.next();
        // must be SOAPBodyElement
        assertTrue(obj instanceof SOAPBodyElement);  
        SOAPElement soapElement = (SOAPElement)obj;
        assertEquals(namespace, soapElement.getNamespaceURI());
        assertEquals(localName, soapElement.getLocalName());
        assertFalse(iter.hasNext());
        
        iter = soapElement.getChildElements();
        assertTrue(iter.hasNext()); 
        obj = iter.next();
        assertTrue(obj instanceof SOAPElement);  
        soapElement = (SOAPElement)obj;
        assertEquals(null, soapElement.getNamespaceURI());
        assertEquals("symbol", soapElement.getLocalName());
        assertFalse(iter.hasNext());
        
        iter = soapElement.getChildElements();
        assertTrue(iter.hasNext()); 
        obj = iter.next();
        assertTrue(obj instanceof Text);  
        Text text = (Text)obj;
        assertEquals("DEF", text.getData());
        assertFalse(iter.hasNext());   
    }
        
}
