package com.icegreen.greenmail.test.specificmessages;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import javax.mail.*;
import javax.mail.internet.*;

import com.icegreen.greenmail.junit.GreenMailRule;
import com.icegreen.greenmail.util.EncodingUtil;
import com.icegreen.greenmail.util.GreenMailUtil;
import com.icegreen.greenmail.util.ServerSetup;
import com.icegreen.greenmail.util.ServerSetupTest;
import com.sun.mail.imap.IMAPStore;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * Tests for encoding scenarios.
 */
public class EncodingTest {
    @Rule
    public GreenMailRule greenMail = new GreenMailRule(ServerSetup.verbose(ServerSetupTest.SMTP_IMAP));

    /**
     * Structure of test message and content type:
     * <p>
     * Message (multipart/alternative)
     * \--> Message (text/plain)
     */
    @Ignore("https://github.com/greenmail-mail-test/greenmail/issues/257")
    @Test
    public void testTextPlainWithUTF8() throws MessagingException, IOException {
        greenMail.setUser("foo@localhost", "pwd");
        final Session session = greenMail.getSmtp().createSession();

        MimeMultipart multipart = new MimeMultipart("alternative");


        MimeBodyPart textQP = new MimeBodyPart();
        textQP.setContent("QP Content with umlaut ü", "text/javascript; charset=utf-8");
        textQP.setHeader("Content-Transfer-Encoding", "QUOTED-PRINTABLE");
        multipart.addBodyPart(textQP);

        MimeBodyPart html = new MimeBodyPart();
        html.setContent("<!doctype html>" +
                "<html lang=en>" +
                "<head>" +
                "<meta charset=utf-8>" +
                "<title>Title with Umlaut ü</title>" +
                "</head>" +
                "<body>" +
                "<p>8BIT Content with umlaut ü</p>" +
                "</body>" +
                "</html>", "text/html; charset=utf-8");
        html.setHeader("Content-Transfer-Encoding", "8BIT");
        multipart.addBodyPart(html);

        MimeBodyPart text = new MimeBodyPart();
        text.setText("8BIT Content with umlaut ü", "utf-8");
        text.setHeader("Content-Transfer-Encoding", "8BIT");
        multipart.addBodyPart(text);


        // New main message, containing body part
        MimeMessage message = new MimeMessage(session);
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("foo@localhost"));
        message.setSubject("Subject ä", "UTF-8");
        message.setFrom(new InternetAddress("foo@localhost"));
        message.setContent(multipart);
        message.saveChanges();

        GreenMailUtil.sendMimeMessage(message);

        final IMAPStore store = greenMail.getImap().createStore();
        store.connect("foo@localhost", "pwd");
        try {
            Folder inboxFolder = store.getFolder("INBOX");
            inboxFolder.open(Folder.READ_WRITE);
            Message[] messages = inboxFolder.getMessages();
            MimeMessage msg = (MimeMessage) messages[0];
            message.writeTo(new FileOutputStream(new File("t.eml")));
            assertTrue(msg.getContentType().startsWith("multipart/alternative"));
            Multipart multipartReceived = (Multipart) msg.getContent();

            assertTrue(multipartReceived.getContentType().startsWith("multipart/alternative"));

            // QP-encoded
            final BodyPart bodyPart0 = multipartReceived.getBodyPart(0);
            assertEquals("TEXT/JAVASCRIPT; charset=utf-8", bodyPart0.getContentType());
            assertEquals(textQP.getContent(), EncodingUtil.toString((InputStream) bodyPart0.getContent(), StandardCharsets.UTF_8));

            // 8-BIT-encoded
            final BodyPart bodyPart1 = multipartReceived.getBodyPart(1);
            assertEquals("TEXT/HTML; charset=utf-8", bodyPart1.getContentType());
            assertEquals(html.getContent(), bodyPart1.getContent()); // Fails

            final BodyPart bodyPart2 = multipartReceived.getBodyPart(2);
            assertEquals("TEXT/PLAIN; charset=utf-8", bodyPart2.getContentType());
            assertEquals(text.getContent(), bodyPart2.getContent());

        } finally {
            store.close();
        }
    }
}

@@ -1486,25 +1486,30 @@
 with umlaut 
-%C3%BC
+%5Cu00FC
 %22, %22text/jav
@@ -1886,17 +1886,22 @@
  Umlaut 
-%C3%BC
+%5Cu00FC
 %3C/title%3E
@@ -2291,17 +2291,22 @@
  umlaut 
-%C3%BC
+%5Cu00FC
 %22, %22utf-

Use unicode for umlauts, to avoid source code encoding issues (issue #257)