/*
 * 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.axiom.om.impl.mtom;

import org.apache.axiom.attachments.Attachments;
import org.apache.axiom.blob.Blob;
import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMOutputFormat;
import org.apache.axiom.om.OMSerializable;
import org.apache.axiom.om.OMText;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.axiom.soap.SOAPModelBuilder;
import org.apache.axiom.ts.soap.MTOMSample;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import junit.framework.TestCase;

public class MTOMStAXSOAPModelBuilderTest extends TestCase {

    @Override
    protected void setUp() throws Exception {
        super.setUp();
    }

    private Attachments createAttachmentsForTestMTOMMessage() throws Exception {
        InputStream inStream = MTOMSample.SAMPLE2.getInputStream();
        return new Attachments(inStream, MTOMSample.SAMPLE2.getContentType());
    }

    private OMElement createTestMTOMMessage() throws Exception {
        return OMXMLBuilderFactory.createSOAPModelBuilder(createAttachmentsForTestMTOMMessage().getMultipartBody()).getDocumentElement();
    }
    
    
    private void checkSerialization(OMElement root, boolean optimize) throws Exception {
        OMOutputFormat format = new OMOutputFormat();
        format.setDoOptimize(optimize);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        root.serialize(baos, format);
        String msg = baos.toString();
        if (optimize) {
            // Make sure there is an xop:Include element and an optimized attachment
            assertTrue(msg.indexOf("xop:Include") > 0);
            assertTrue(msg.indexOf("Content-ID: <-1609420109260943731>") > 0);
        } else {
            assertTrue(msg.indexOf("xop:Include") < 0);
            assertTrue(msg.indexOf("Content-ID: <-1609420109260943731>") < 0);
        }
    }
    
    public void testCreateOMElement() throws Exception {
        OMElement root = createTestMTOMMessage();
        OMElement body = (OMElement) root.getFirstOMChild();
        OMElement data = (OMElement) body.getFirstOMChild();

        Iterator childIt = data.getChildren();
        OMElement child = (OMElement) childIt.next();
        OMText blobNode = (OMText) child.getFirstOMChild();
        /*
         * Following is the procedure the user has to follow to read objects in
         * OBBlob User has to know the object type & whether it is serializable.
         * If it is not he has to use a Custom Defined DataSource to get the
         * Object.
         */
        byte[] expectedObject = new byte[] { 13, 56, 65, 32, 12, 12, 7, -3, -2,
                -1, 98 };
        Blob actualBlob = blobNode.getBlob();
        //ByteArrayInputStream object = (ByteArrayInputStream) actualDH
        //.getContent();
        //byte[] actualObject= null;
        //  object.read(actualObject,0,10);

        //  assertEquals("Object check", expectedObject[5],actualObject[5] );
    }

    /**
     * Test that MIME parts are not loaded before requesting the DataHandlers from the corresponding
     * OMText nodes.
     *  
     * @throws Exception
     */
    public void testDeferredLoadingOfAttachments() throws Exception {
        Attachments attachments = createAttachmentsForTestMTOMMessage();
        SOAPModelBuilder builder = OMXMLBuilderFactory.createSOAPModelBuilder(attachments.getMultipartBody());
        OMDocument doc = builder.getDocument();
        // Find all the binary nodes
        List<OMText> binaryNodes = new ArrayList<>();
        for (Iterator<OMSerializable> it = doc.getDescendants(false); it.hasNext(); ) {
            OMSerializable node = it.next();
            if (node instanceof OMText) {
                OMText text = (OMText)node;
                if (text.isBinary()) {
                    binaryNodes.add(text);
                }
            }
        }
        assertFalse(binaryNodes.isEmpty());
        // At this moment only the SOAP part should have been loaded
        assertEquals(1, attachments.getContentIDList().size());
        for (OMText node : binaryNodes) {
            // Request the Blob and do something with it to make sure
            // the part is loaded
            node.getBlob().getInputStream().close();
        }
        assertEquals(binaryNodes.size() + 1, attachments.getContentIDList().size());
    }
    
    /**
     * Test reading a message containing XOP and ensuring that the
     * the XOP is preserved when it is serialized.
     * @throws Exception
     */
    public void testCreateAndSerializeOptimized() throws Exception {
        OMElement root = createTestMTOMMessage();
        checkSerialization(root, true);
    }
    
    /**
     * Test reading a message containing XOP.
     * Then make a copy of the message.
     * Then ensure that the XOP is preserved when it is serialized.
     * @throws Exception
     */
    public void testCreateCloneAndSerializeOptimized() throws Exception {
        OMElement root = createTestMTOMMessage();
        
        // Create a clone of root
        OMElement root2 = root.cloneOMElement();
        
        // Write out the source
        checkSerialization(root, true);
        
        // Write out the clone
        checkSerialization(root2, true);
    }
    
    /**
     * Test reading a message containing XOP.
     * Fully build the tree.
     * Then make a copy of the message.
     * Then ensure that the XOP is preserved when it is serialized.
     * @throws Exception
     */
    public void testCreateBuildCloneAndSerializeOptimized() throws Exception {
        OMElement root = createTestMTOMMessage();
        
        // Fully build the root
        root.buildWithAttachments();
        
        // Create a clone of root
        OMElement root2 = root.cloneOMElement();
        
        // Write out the source
        checkSerialization(root, true);
        
        // Write out the clone
        checkSerialization(root2, true);
    }
    
    /**
     * Test reading a message containing XOP.
     * Serialize the tree (with caching).
     * Then ensure that the XOP is preserved when it is serialized again.
     * <p>
     * Regression test for AXIOM-264.
     * 
     * @throws Exception
     */
    public void testCreateSerializeAndSerializeOptimized() throws Exception {
        OMElement root = createTestMTOMMessage();
        
        // Serialize the tree (with caching).
        root.serialize(new ByteArrayOutputStream());
        
        // Write out the source
        checkSerialization(root, true);
    }
    
    /**
     * Test reading a message containing XOP.
     * Enable inlining serialization
     * Then ensure that the data is inlined when written
     * @throws Exception
     */
    public void testCreateAndSerializeInlined() throws Exception {
        OMElement root = createTestMTOMMessage();
        
        checkSerialization(root, false);
    }

    public void testUTF16MTOMMessage() throws Exception {
        String contentTypeString =
                "multipart/Related; charset=\"UTF-8\"; type=\"application/xop+xml\"; boundary=\"----=_AxIs2_Def_boundary_=42214532\"; start=\"SOAPPart\"";
        String cid = "1.urn:uuid:A3ADBAEE51A1A87B2A11443668160994@apache.org";
        String xmlPlusMime1 = "------=_AxIs2_Def_boundary_=42214532\r\n" +
                "Content-Type: application/xop+xml; charset=UTF-16; type=\"application/soap+xml\"\r\n" +
                "Content-Transfer-Encoding: 8bit\r\n" +
                "Content-ID: SOAPPart\r\n" +
                "\r\n";
        String xmlPlusMime2 = "<soapenv:Envelope xmlns:soapenv=\"http://www.w3.org/2003/05/soap-envelope\"><soapenv:Body><m:data xmlns:m=\"http://www.example.org/stuff\"><m:name m:contentType=\"text/plain\"><xop:Include xmlns:xop=\"http://www.w3.org/2004/08/xop/include\" href=\"cid:" + cid + "\"></xop:Include></m:name></m:data></soapenv:Body></soapenv:Envelope>\r\n";
        String xmlPlusMime3 = "\r\n------=_AxIs2_Def_boundary_=42214532\r\n" +
                "Content-Transfer-Encoding: binary\r\n" +
                "Content-ID: " + cid + "\r\n" +
                "\r\n" +
                "Foo Bar\r\n" +
                "------=_AxIs2_Def_boundary_=42214532--\r\n";
        byte[] bytes1 = xmlPlusMime1.getBytes();
        byte[] bytes2 = xmlPlusMime2.getBytes(StandardCharsets.UTF_16);
        byte[] bytes3 = xmlPlusMime3.getBytes();
        byte[] full = append(bytes1, bytes2);
        full = append(full, bytes3);
        
        InputStream inStream = new BufferedInputStream(new ByteArrayInputStream(full));
        Attachments attachments = new Attachments(inStream, contentTypeString);
        SOAPModelBuilder builder = OMXMLBuilderFactory.createSOAPModelBuilder(attachments.getMultipartBody());
        OMElement root = builder.getDocumentElement();
        root.build();
    }

    private byte[] append(byte[] a, byte[] b) {
        byte[] z = new byte[a.length + b.length];
        System.arraycopy(a, 0, z, 0, a.length);
        System.arraycopy(b, 0, z, a.length, b.length);
        return z;
    }
}