/*
 * 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.chemistry.opencmis.server.impl;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
import org.apache.chemistry.opencmis.server.impl.browser.MultipartParser;
import org.apache.chemistry.opencmis.server.shared.ThresholdOutputStreamFactory;
import org.junit.Test;

/**
 * Tests the multipart parser.
 */
public class MultipartParserTest {

    private static final int THRESHOLD = 4 * 1024 * 1024;
    private static final int MAX_SIZE = -1;

    @Test
    public void testMultipartParser() throws Exception {
        String boundary = "---- next ----";
        byte[] content = "This is content!".getBytes();
        byte[] formdata = ("\r\n--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n"
                + "\r\n" + "value1\r\n" + "--" + boundary + "\r\n"
                + "content-disposition: form-data; name=\"field2\"\r\n" + "\r\n" + "value2\r\n" + "--" + boundary
                + "\r\n" + "content-disposition: form-data; name=\"field3\"\r\n" + "\r\n" + "value3\r\n" + "--"
                + boundary + "\r\n"
                + "Content-Disposition: form-data; name=\"content\"; filename=test-filename.txt\r\n"
                + "Content-Type: text/plain\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n"
                + new String(content) + "\r\n" + "--" + boundary + "--").getBytes("ISO-8859-1");

        MultipartParser parser = prepareParser(boundary, formdata);

        Map<String, String> values = new HashMap<String, String>();
        values.put("field1", "value1");
        values.put("field2", "value2");
        values.put("field3", "value3");

        assertMultipartBasics(parser, 4, values, true, "test-filename.txt", "text/plain", content);
    }

    @Test
    public void testMultipartParser2() throws Exception {
        String boundary = "-----------------------------1294919323195";
        byte[] content = "Test content!".getBytes("ISO-8859-1");
        byte[] formdata = ("\r\n--"
                + boundary
                + "\r\nContent-Disposition: form-data; name=\"fileUploader\"; filename=\"ä.txt\"\r\nContent-Type: text/plain\r\n\r\n"
                + new String(content) + "\r\n--" + boundary
                + "\r\nContent-Disposition: form-data; name=\"fileUploader-data\"\r\n\r\n\r\n--" + boundary
                + "\r\nContent-Disposition: form-data; name=\"objectid\"\r\n\r\nf6bad54b4696bf2ac9249805\r\n--"
                + boundary + "\r\nContent-Disposition: form-data; name=\"cmisaction\"\r\n\r\ncreateDocument\r\n--"
                + boundary + "\r\nContent-Disposition: form-data; name=\"propertyId[0]\"\r\n\r\ncmis:name\r\n--"
                + boundary + "\r\nContent-Disposition: form-data; name=\"propertyValue[0]\"\r\n\r\nä.txt\r\n--"
                + boundary
                + "\r\nContent-Disposition: form-data; name=\"propertyId[1]\"\r\n\r\ncmis:objectTypeId\r\n--"
                + boundary + "\r\nContent-Disposition: form-data; name=\"propertyValue[1]\"\r\n\r\ncmis:document\r\n--"
                + boundary
                + "\r\nContent-Disposition: form-data; name=\"token\"\r\n\r\n855475d8a6169b5f57111f5921f56136\r\n--"
                + boundary + "--").getBytes("ISO-8859-1");

        MultipartParser parser = prepareParser(boundary, formdata);

        Map<String, String> values = new HashMap<String, String>();
        values.put("fileUploader-data", "");
        values.put("objectid", "f6bad54b4696bf2ac9249805");
        values.put("cmisaction", "createDocument");
        values.put("propertyId[0]", "cmis:name");
        values.put("propertyValue[0]", "ä.txt");
        values.put("propertyId[1]", "cmis:objectTypeId");
        values.put("propertyValue[1]", "cmis:document");
        values.put("token", "855475d8a6169b5f57111f5921f56136");

        assertMultipartBasics(parser, 9, values, true, "ä.txt", "text/plain", content);
    }

    @Test
    public void testNoPreamble() throws Exception {
        String boundary = "BoUnDaRy--987654320";
        byte[] formdata = ("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n" + "\r\n"
                + "value1\r\n" + "--" + boundary + "--").getBytes();

        MultipartParser parser = prepareParser(boundary, formdata);

        Map<String, String> values = new HashMap<String, String>();
        values.put("field1", "value1");

        assertMultipartBasics(parser, 1, values, false, null, null, null);
    }

    @Test
    public void testPreamble() throws Exception {
        String boundary = "BoUnDaRy--987654320";
        byte[] formdata = ("This is a preamble.\r\n--" + boundary + "\r\n"
                + "Content-Disposition: form-data; name=\"field1\"\r\n" + "\r\n" + "value1\r\n" + "--" + boundary + "--")
                .getBytes();

        MultipartParser parser = prepareParser(boundary, formdata);

        Map<String, String> values = new HashMap<String, String>();
        values.put("field1", "value1");

        assertMultipartBasics(parser, 1, values, false, null, null, null);
    }

    @Test
    public void testEpilogue() throws Exception {
        String boundary = "BoUnDaRy--987654320";
        byte[] formdata = ("\r\n--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n"
                + "\r\n" + "value1\r\n" + "--" + boundary + "--This is an epilogue.").getBytes();

        MultipartParser parser = prepareParser(boundary, formdata);

        Map<String, String> values = new HashMap<String, String>();
        values.put("field1", "value1");

        assertMultipartBasics(parser, 1, values, false, null, null, null);
    }

    @Test
    public void testEmpty() throws Exception {
        String boundary = "BoUnDaRy--987654320";
        byte[] formdata = ("\r\n--" + boundary + "--").getBytes();

        MultipartParser parser = prepareParser(boundary, formdata);

        Map<String, String> values = new HashMap<String, String>();

        assertMultipartBasics(parser, 0, values, false, null, null, null);
    }

    @Test
    public void testContentOnly() throws Exception {
        String boundary = "ABCD-1234";
        byte[] content = "abcäöü".getBytes();
        byte[] formdata = ("\r\n--" + boundary + "\r\n"
                + "Content-Disposition: form-data; name=\"content\"; filename=\"a new file\"\r\n"
                + "Content-Type: application/something\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n"
                + new String(content) + "\r\n" + "--" + boundary + "--").getBytes();

        MultipartParser parser = prepareParser(boundary, formdata);

        Map<String, String> values = new HashMap<String, String>();

        assertMultipartBasics(parser, 1, values, true, "a new file", "application/something", content);
    }

    @Test
    public void testBigContent() throws Exception {
        String boundary = "---- next ----";
        byte[] content = new byte[2 * 1024 * 1024];

        Random rnd = new Random();
        for (int i = 0; i < content.length; i++) {
            content[i] = (byte) ('a' + rnd.nextInt('z' - 'a'));
        }

        byte[] formdata = ("\r\n--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n"
                + "\r\n" + "value1\r\n" + "--" + boundary + "\r\n"
                + "content-disposition: form-data; name=\"field2\"\r\n" + "\r\n" + "value2\r\n" + "--" + boundary
                + "\r\n" + "content-disposition: form-data; name=\"field3\"\r\n" + "\r\n" + "value3\r\n" + "--"
                + boundary + "\r\n" + "Content-Disposition: form-data; name=\"content\"; filename=bigtest.txt\r\n"
                + "Content-Type: text/plain\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n"
                + new String(content) + "\r\n" + "--" + boundary + "--").getBytes();

        MultipartParser parser = prepareParser(boundary, formdata);

        Map<String, String> values = new HashMap<String, String>();
        values.put("field1", "value1");
        values.put("field2", "value2");
        values.put("field3", "value3");

        assertMultipartBasics(parser, 4, values, true, "bigtest.txt", "text/plain", content);
    }

    @Test
    public void testManyField() throws Exception {
        String boundary = "============";

        StringBuilder sb = new StringBuilder("\r\n");

        Map<String, String> values = new HashMap<String, String>();

        for (int i = 0; i < 10000; i++) {
            String name = "field" + i;
            String value = "value " + i * i;

            values.put(name, value);

            sb.append("\r\n--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"" + name + "\"\r\n"
                    + "\r\n" + value);
        }

        sb.append("\r\n" + "--" + boundary + "--");

        MultipartParser parser = prepareParser(boundary, sb.toString().getBytes());

        assertMultipartBasics(parser, values.size(), values, false, null, null, null);
    }

    @Test
    public void testCharsetsInContentType() throws Exception {
        String[] charsets = new String[] { "utf-8", "iso-8859-1", "utf-16" };

        String boundary = "ldchqeriuvoqeirbvxipu  eckqnqklwjcnqwklcqwncqewlciqecqwecevoipooei cqwcoewcq";
        StringBuilder value = new StringBuilder();

        for (int i = 1; i < 255; i++) {
            value.append((char) i);
        }

        Map<String, String> values = new HashMap<String, String>();
        values.put("field1", value.toString());

        for (String charset : charsets) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bos.write(("\r\n--" + boundary + "\r\n").getBytes("ISO-8859-1"));
            bos.write(("Content-Disposition: form-data; name=\"field1\"\r\n").getBytes("ISO-8859-1"));
            bos.write(("Content-Type: text/plain; charset=" + charset + "\r\n\r\n").getBytes("ISO-8859-1"));
            bos.write(value.toString().getBytes(charset));
            bos.write(("\r\n--" + boundary + "--\r\n").getBytes("ISO-8859-1"));
            bos.write(("This is an epilogue.").getBytes("ISO-8859-1"));

            MultipartParser parser = prepareParser(boundary, bos.toByteArray());

            assertMultipartBasics(parser, 1, values, false, null, null, null);
        }
    }

    @Test
    public void testCharsetsAsExtraField() throws Exception {
        String[] charsets = new String[] { "utf-8", "iso-8859-1", "utf-16" };

        String boundary = "ldchqeriuvoqeirbvxipu  eckqnqklwjcnqwklcqwncqewlciqecqwecevoipooei cqwcoewcq";
        StringBuilder value = new StringBuilder();

        for (int i = 1; i < 255; i++) {
            value.append((char) i);
        }

        Map<String, String> values = new HashMap<String, String>();
        values.put("field1", value.toString());

        for (String charset : charsets) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bos.write(("\r\n--" + boundary + "\r\n").getBytes("ISO-8859-1"));
            bos.write(("Content-Disposition: form-data; name=\"field1\"\r\n\r\n").getBytes("ISO-8859-1"));
            bos.write(value.toString().getBytes(charset));
            bos.write(("\r\n--" + boundary + "\r\n").getBytes("ISO-8859-1"));
            bos.write(("Content-Disposition: form-data; name=\"_charset_\"\r\n\r\n").getBytes("ISO-8859-1"));
            bos.write(charset.getBytes("ISO-8859-1"));
            bos.write(("\r\n--" + boundary + "--\r\n").getBytes("ISO-8859-1"));
            bos.write(("This is an epilogue.").getBytes("ISO-8859-1"));

            MultipartParser parser = prepareParser(boundary, bos.toByteArray());

            assertMultipartBasics(parser, 1, values, false, null, null, null);
        }
    }

    @Test
    public void testCharsetsMixed() throws Exception {
        String[] charsets = new String[] { "utf-8", "iso-8859-1", "utf-16" };

        String boundary = "ldchqeriuvoqeirbvxipu  eckqnqklwjcnqwklcqwncqewlciqecqwecevoipooei cqwcoewcq";
        StringBuilder value = new StringBuilder();

        for (int i = 1; i < 255; i++) {
            value.append((char) i);
        }

        Map<String, String> values = new HashMap<String, String>();
        values.put("field1", value.toString());
        values.put("field2", value.toString());
        values.put("field3", value.toString());

        for (String charset : charsets) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bos.write(("\r\n--" + boundary + "\r\n").getBytes("ISO-8859-1"));
            bos.write(("Content-Disposition: form-data; name=\"field1\"\r\n").getBytes("ISO-8859-1"));
            bos.write(("Content-Type: text/plain; charset=\"utf-8\"\r\n\r\n").getBytes("ISO-8859-1"));
            bos.write(value.toString().getBytes("utf-8"));
            bos.write(("\r\n--" + boundary + "\r\n").getBytes("ISO-8859-1"));
            bos.write(("Content-Disposition: form-data; name=\"field2\"\r\n\r\n").getBytes("ISO-8859-1"));
            bos.write(value.toString().getBytes(charset));
            bos.write(("\r\n--" + boundary + "\r\n").getBytes("ISO-8859-1"));
            bos.write(("Content-Disposition: form-data; name=\"_charset_\"\r\n\r\n").getBytes("ISO-8859-1"));
            bos.write(charset.getBytes("ISO-8859-1"));
            bos.write(("\r\n--" + boundary + "\r\n").getBytes("ISO-8859-1"));
            bos.write(("Content-Disposition: form-data; name=\"field3\"\r\n\r\n").getBytes("ISO-8859-1"));
            bos.write(value.toString().getBytes(charset));
            bos.write(("\r\n--" + boundary + "--\r\n").getBytes("ISO-8859-1"));

            MultipartParser parser = prepareParser(boundary, bos.toByteArray());

            assertMultipartBasics(parser, 3, values, false, null, null, null);
        }
    }

    @Test(expected = CmisInvalidArgumentException.class)
    public void testNoBoundary() throws Exception {
        String boundary = "";
        byte[] formdata = ("\r\n--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n"
                + "\r\n" + "value1\r\n" + "--" + boundary + "--").getBytes();

        prepareParser(boundary, formdata);
    }

    @Test(expected = CmisInvalidArgumentException.class)
    public void testInvalidCharset() throws Exception {
        String boundary = "15983409582340582340";
        byte[] formdata = ("\r\n--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n"
                + "Content-Type: text/plain; charset=xyz\r\n" + "\r\n" + "value1\r\n" + "--" + boundary + "--")
                .getBytes();

        MultipartParser parser = prepareParser(boundary, formdata);

        assertMultipartBasics(parser, 1, null, false, null, null, null);
    }

    @Test(expected = CmisInvalidArgumentException.class)
    public void testTwoContentParts() throws Exception {
        String boundary = "-?-";
        byte[] content = "abcäöü".getBytes();
        byte[] formdata = ("\r\n--" + boundary + "\r\n"
                + "Content-Disposition: form-data; name=\"content1\"; filename=\"file1\"\r\n"
                + "Content-Type: application/something\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n"
                + new String(content) + "\r\n--" + boundary + "\r\n"
                + "Content-Disposition: form-data; name=\"content2\"; filename=\"file2\"\r\n"
                + "Content-Type: application/something\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n"
                + new String(content) + "\r\n" + "--" + boundary + "--").getBytes();

        MultipartParser parser = prepareParser(boundary, formdata);

        assertMultipartBasics(parser, 2, null, true, "file1", "application/something", content);
    }

    // ---- helpers ----

    private MultipartParser prepareParser(String boundary, byte[] content) throws Exception {
        HttpServletRequest request = HttpRequestMockHelper.createRequest(boundary, content);

        ThresholdOutputStreamFactory streamFactory = ThresholdOutputStreamFactory.newInstance(null, THRESHOLD,
                MAX_SIZE, false);
        return new MultipartParser(request, streamFactory);
    }

    private byte[] readBytesFromStream(InputStream is) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        byte[] buffer = new byte[4096];
        int b;
        while ((b = is.read(buffer)) > -1) {
            bos.write(buffer, 0, b);
        }

        is.close();

        return bos.toByteArray();
    }

    private void assertMultipartBasics(MultipartParser parser, int count, Map<String, String> values,
            boolean hasContent, String filename, String contentType, byte[] content) throws Exception {
        int counter = 0;

        parser.parse();

        if (parser.hasContent()) {
            counter++;
            assertTrue(hasContent);
            assertEquals(filename, parser.getFilename());
            assertEquals(contentType, parser.getContentType());
            assertEquals(content.length, parser.getSize().intValue());
            assertArrayEquals(content, readBytesFromStream(parser.getStream()));
        } else {
            assertFalse(hasContent);
        }

        Map<String, String[]> fields = parser.getFields();
        for (Map.Entry<String, String[]> e : fields.entrySet()) {
            assertNotNull(e.getValue());
            assertEquals(1, e.getValue().length);

            String fieldName = e.getKey();
            String fieldValue = e.getValue()[0];

            assertEquals(fieldValue, values.get(fieldName));

            counter++;
        }

        assertEquals(count, counter);
        assertEquals(counter - (hasContent ? 1 : 0), fields.size());
    }
}
