/****************************************************************
 * 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.james.mime4j.codec;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

import org.apache.james.mime4j.Charsets;
import org.apache.james.mime4j.codec.EncoderUtil.Encoding;
import org.apache.james.mime4j.codec.EncoderUtil.Usage;
import org.apache.james.mime4j.io.InputStreams;
import org.apache.james.mime4j.util.ContentUtil;
import org.junit.Assert;
import org.junit.Test;

public class EncoderUtilTest {

    @Test
    public void testEncodeAddressDisplayName() throws Exception {
        Assert.assertEquals("\"\"", EncoderUtil.encodeAddressDisplayName(""));
        Assert.assertEquals("test", EncoderUtil.encodeAddressDisplayName("test"));
        Assert.assertEquals(" test ", EncoderUtil.encodeAddressDisplayName(" test "));
        Assert.assertEquals(" test\ttest ", EncoderUtil
                .encodeAddressDisplayName(" test\ttest "));
        Assert.assertEquals("\"test()\"", EncoderUtil
                .encodeAddressDisplayName("test()"));
        Assert.assertEquals("\"John Q. Public\"", EncoderUtil
                .encodeAddressDisplayName("John Q. Public"));
        Assert.assertEquals("\"Giant; \\\"Big\\\" Box\"", EncoderUtil
                .encodeAddressDisplayName("Giant; \"Big\" Box"));
        Assert.assertEquals("=?ISO-8859-1?Q?Semmelbr=F6sel?=", EncoderUtil
                .encodeAddressDisplayName("Semmelbr\366sel"));
        // dollar sign as to be encoded as =24 when used as a word in a phrase
        Assert.assertEquals("=?UTF-8?Q?Dollar_=24_Euro_=E2=82=AC?=", EncoderUtil
                .encodeAddressDisplayName("Dollar $ Euro \u20ac"));
    }

    @Test
    public void testEncodeAddressLocalPart() throws Exception {
        Assert.assertEquals("john.wayne", EncoderUtil
                .encodeAddressLocalPart("john.wayne"));
        Assert.assertEquals("\"clint eastwood\"", EncoderUtil
                .encodeAddressLocalPart("clint eastwood"));
    }

    @Test
    public void testEncodeHeaderParameter() throws Exception {
        Assert.assertEquals("p=test", EncoderUtil.encodeHeaderParameter("p", "test"));
        Assert.assertEquals("p=\"test test\"", EncoderUtil.encodeHeaderParameter("p",
                "test test"));
        Assert.assertEquals("p=\"=test\"", EncoderUtil.encodeHeaderParameter("p",
                "=test"));
        Assert.assertEquals("p=\"\\\\test\"", EncoderUtil.encodeHeaderParameter("p",
                "\\test"));
        Assert.assertEquals("p=\"\\\"\\\\\\\"\"", EncoderUtil.encodeHeaderParameter(
                "p", "\"\\\""));
    }

    @Test
    public void testHasToBeEncoded() throws Exception {
        Assert.assertFalse(EncoderUtil.hasToBeEncoded("", 0));
        Assert.assertFalse(EncoderUtil.hasToBeEncoded("only ascii characters", 0));

        Assert.assertTrue(EncoderUtil.hasToBeEncoded("non-printable ascii: \010", 0));
        Assert.assertTrue(EncoderUtil.hasToBeEncoded("non-ascii: \u20ac", 0));

        Assert.assertFalse(EncoderUtil.hasToBeEncoded("123456789012345678901234567",
                50));
        Assert.assertTrue(EncoderUtil.hasToBeEncoded("1234567890123456789012345678",
                50));
        Assert.assertFalse(EncoderUtil.hasToBeEncoded(
                "\t12345678901234567890123456789", 50));
    }

    @Test
    public void testEncodeEncodedWordDetectCharset() throws Exception {
        Assert.assertTrue(EncoderUtil
                .encodeEncodedWord("only ascii", Usage.TEXT_TOKEN).startsWith(
                        "=?US-ASCII?"));
        Assert.assertTrue(EncoderUtil.encodeEncodedWord("latin 1: \344",
                Usage.TEXT_TOKEN).startsWith("=?ISO-8859-1?"));
        Assert.assertTrue(EncoderUtil.encodeEncodedWord("unicode: \u20ac",
                Usage.TEXT_TOKEN).startsWith("=?UTF-8?"));
    }

    @Test
    public void testEncodeEncodedWordForceCharset() throws Exception {
        Assert.assertTrue(EncoderUtil.encodeEncodedWord("only ascii",
                Usage.TEXT_TOKEN, 0, Charsets.UTF_8, null).startsWith(
                "=?UTF-8?"));
    }

    @Test
    public void testEncodeEncodedWordDetectEncoding() throws Exception {
        Assert.assertTrue(EncoderUtil
                .encodeEncodedWord("only ascii", Usage.TEXT_TOKEN).startsWith(
                        "=?US-ASCII?Q?"));
        Assert.assertTrue(EncoderUtil.encodeEncodedWord("\344\344\344\344\344",
                Usage.TEXT_TOKEN).startsWith("=?ISO-8859-1?B?"));
    }

    @Test
    public void testEncodeEncodedWordForceEncoding() throws Exception {
        Assert.assertTrue(EncoderUtil.encodeEncodedWord("only ascii",
                Usage.TEXT_TOKEN, 0, null, Encoding.B).startsWith(
                "=?US-ASCII?B?"));
    }

    @Test
    public void testEncodeEncodedWordSplit() throws Exception {
        String sixty = "123456789012345678901234567890123456789012345678901234567890";

        String expected = "=?US-ASCII?Q?" + sixty + "?=";
        Assert.assertEquals(expected, EncoderUtil.encodeEncodedWord(sixty,
                Usage.TEXT_TOKEN, 0, null, Encoding.Q));
        Assert.assertEquals(75, expected.length());

        String sixtyOne = sixty + "1";
        String encodedSixtyOne = EncoderUtil.encodeEncodedWord(sixtyOne,
                Usage.TEXT_TOKEN, 0, null, Encoding.Q);
        Assert.assertTrue(encodedSixtyOne.contains("?= =?US-ASCII?Q?"));
    }
    
    @Test
    public void testEncodeBEncodedWordSplitForUnicode() throws Exception {
        StringBuilder sb = new StringBuilder("z");
        for (int i = 0; i < 10; i++) {
            // Append unicode character 𝕫 10 times.
            sb.append("\uD835\uDD6b");
        }

        String expected = "=?UTF-8?B?evCdlavwnZWr8J2Vq/Cdlas=?= " +
                "=?UTF-8?B?8J2Vq/CdlavwnZWr8J2Vq/CdlavwnZWr?=";
        Assert.assertEquals(expected, EncoderUtil.encodeEncodedWord(sb.toString(),
                Usage.TEXT_TOKEN, 10, null, Encoding.B));
    }

    @Test
    public void testEncodeQEncodedWordSplitForUnicode() throws Exception {
        StringBuilder sb = new StringBuilder("z");
        for (int i = 0; i < 6; i++) {
            // Append unicode character 𝕫 6 times.
            sb.append("\uD835\uDD6b");
        }

        String expected = "=?UTF-8?Q?z=F0=9D=95=AB=F0=9D=95=AB?= " +
                "=?UTF-8?Q?=F0=9D=95=AB=F0=9D=95=AB=F0=9D=95=AB=F0=9D=95=AB?=";
        Assert.assertEquals(expected, EncoderUtil.encodeEncodedWord(sb.toString(),
                Usage.TEXT_TOKEN, 10, null, Encoding.Q));
    }

    @Test
    public void testEncodeEncodedWord() throws Exception {
        Assert.assertEquals("=?US-ASCII?Q??=", EncoderUtil.encodeEncodedWord("",
                Usage.TEXT_TOKEN, 0, null, Encoding.Q));

        Assert.assertEquals("=?US-ASCII?Q?testing_123?=", EncoderUtil
                .encodeEncodedWord("testing 123", Usage.TEXT_TOKEN, 0, null,
                        Encoding.Q));

        Assert.assertEquals("=?US-ASCII?B?dGVzdGluZyAxMjM=?=", EncoderUtil
                .encodeEncodedWord("testing 123", Usage.TEXT_TOKEN, 0, null,
                        Encoding.B));

        Assert.assertEquals("=?windows-1252?Q?100_=80?=", EncoderUtil
                .encodeEncodedWord("100 \u20ac", Usage.TEXT_TOKEN, 0, Charset
                        .forName("Cp1252"), Encoding.Q));

        Assert.assertEquals("=?windows-1252?B?MTAwIIA=?=", EncoderUtil
                .encodeEncodedWord("100 \u20ac", Usage.TEXT_TOKEN, 0, Charset
                        .forName("Cp1252"), Encoding.B));
    }

    @Test
    public void testEncodeB() throws Exception {
        Assert.assertEquals("", encodeB(""));
        Assert.assertEquals("YQ==", encodeB("a"));
        Assert.assertEquals("YWI=", encodeB("ab"));
        Assert.assertEquals("YWJj", encodeB("abc"));
        Assert.assertEquals("YWJjZA==", encodeB("abcd"));
        Assert.assertEquals("YWJjZGU=", encodeB("abcde"));
        Assert.assertEquals("YWJjZGVm", encodeB("abcdef"));
        Assert.assertEquals("YWJjZGVmZw==", encodeB("abcdefg"));
        Assert.assertEquals("YWJjZGVmZ2g=", encodeB("abcdefgh"));
        Assert.assertEquals("YWJjZGVmZ2hp", encodeB("abcdefghi"));
        Assert.assertEquals("DQoMCQ==", encodeB("\r\n\f\t"));
        Assert.assertEquals("LT0/VGhhdCdzIGEgdGVzdD89LQ==",
                encodeB("-=?That's a test?=-"));
    }

    @Test
    public void testEncodeQRegular() throws Exception {
        byte[] b = new byte[132];
        for (int i = 0; i < 132; i++) {
            b[i] = (byte) i;
        }

        String expected = "=00=01=02=03=04=05=06=07=08=09=0A=0B=0C=0D=0E=0F"
                + "=10=11=12=13=14=15=16=17=18=19=1A=1B=1C=1D=1E=1F_!\"#$%&"
                + "'()*+,-./0123456789:;<=3D>=3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                + "[\\]^=5F`abcdefghijklmnopqrstuvwxyz{|}~=7F=80=81=82=83";
        Assert.assertEquals(expected, EncoderUtil.encodeQ(b, Usage.TEXT_TOKEN));
    }

    @Test
    public void testEncodeQRestricted() throws Exception {
        byte[] b = new byte[136];
        for (int i = 0; i < 136; i++) {
            b[i] = (byte) i;
        }

        String expected = "=00=01=02=03=04=05=06=07=08=09=0A=0B=0C=0D=0E=0F"
                + "=10=11=12=13=14=15=16=17=18=19=1A=1B=1C=1D=1E=1F_!=22=23"
                + "=24=25=26=27=28=29*+=2C-=2E/0123456789=3A=3B=3C=3D=3E=3F"
                + "=40ABCDEFGHIJKLMNOPQRSTUVWXYZ=5B=5C=5D=5E=5F=60abcdefghi"
                + "jklmnopqrstuvwxyz=7B=7C=7D=7E=7F=80=81=82=83=84=85=86=87";
        Assert.assertEquals(expected, EncoderUtil.encodeQ(b, Usage.WORD_ENTITY));
    }

    private String encodeB(String s) {
        try {
            return EncoderUtil.encodeB(s.getBytes("us-ascii"));
        } catch (UnsupportedEncodingException e) {
            throw new Error(e);
        }
    }

    @Test
    public void testEncodeQuotedPrintableLargeInput() throws Exception {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 1024 * 5; i++) {
            sb.append((char) ('0' + (i % 10)));
        }
        String expected = sb.toString().replaceAll("(\\d{75})", "$1=\r\n");

        InputStream in = InputStreams.createAscii(sb.toString());
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        EncoderUtil.encodeQBinary(in, out);
        String actual = ContentUtil.toAsciiString(out.toByteArray());
        Assert.assertEquals(expected, actual);
    }

    @Test
    public void testEncodeQuotedPrintableNonAsciiChars() throws Exception {
        String s = "7bit content with euro \u20AC symbol";
        InputStream in = InputStreams.create(s, Charset.forName("iso-8859-15"));
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        EncoderUtil.encodeQBinary(in, out);
        String actual = new String(out.toByteArray(), "US-ASCII");
        Assert.assertEquals("7bit=20content=20with=20euro=20=A4=20symbol", actual);
    }

    @Test
    public void testBase64OutputStream() throws Exception {
        StringBuilder sb = new StringBuilder(2048);
        for (int i = 0; i < 128; i++) {
            sb.append("0123456789ABCDEF");
        }
        String input = sb.toString();
        String output = roundtripUsingOutputStream(input);
        Assert.assertEquals(input, output);
    }

    private String roundtripUsingOutputStream(String input) throws IOException {
        ByteArrayOutputStream out2 = new ByteArrayOutputStream();
        Base64OutputStream outb64 = new Base64OutputStream(out2, 76);
        ContentUtil.copy(InputStreams.create(input, Charsets.ISO_8859_1), outb64);
        outb64.flush();
        outb64.close();

        InputStream is = new Base64InputStream(InputStreams.create(out2.toByteArray()));
        byte[] buf = ContentUtil.buffer(is);
        return ContentUtil.toAsciiString(buf);
    }

    /**
     * This test is a proof for MIME4J-67
     */
    @Test
    public void testBase64Encoder() throws Exception {
        StringBuilder sb = new StringBuilder(2048);
        for (int i = 0; i < 128; i++) {
            sb.append("0123456789ABCDEF");
        }
        String input = sb.toString();
        String output = roundtripUsingEncoder(input);
        Assert.assertEquals(input, output);
    }

    private String roundtripUsingEncoder(String input) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        EncoderUtil.encodeB(InputStreams.createAscii(input), out);

        InputStream is = new Base64InputStream(InputStreams.create(out.toByteArray()));
        byte[] buf = ContentUtil.buffer(is);
        return ContentUtil.toAsciiString(buf);
    }

}
