/*
 * 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.commons.mail;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.activation.FileDataSource;
import javax.activation.URLDataSource;
import javax.mail.internet.MimeMultipart;

import org.apache.commons.mail.mocks.MockMultiPartEmailConcrete;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

/**
 * JUnit test case for MultiPartEmail Class.
 *
 * @since 1.0
 * @version $Id$
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest( { MockMultiPartEmailConcrete.class, URLDataSource.class })
public class MultiPartEmailTest extends AbstractEmailTest
{
    /** */
    private MockMultiPartEmailConcrete email;
    /** File to used to test file attachments (Must be valid) */
    private File testFile;

    @Before
    public void setUpMultiPartEmailTest() throws Exception
    {
        // reusable objects to be used across multiple tests
        this.email = new MockMultiPartEmailConcrete();
        testFile = File.createTempFile("testfile", ".txt");
    }

    @Test
    public void testSetMsg() throws EmailException
    {
        // ====================================================================
        // Test Success
        // ====================================================================

        // without charset set
        for (String validChar : testCharsValid)
        {
            this.email.setMsg(validChar);
            assertEquals(validChar, this.email.getMsg());
        }

        // with charset set
        this.email.setCharset(EmailConstants.US_ASCII);
        for (String validChar : testCharsValid)
        {
            this.email.setMsg(validChar);
            assertEquals(validChar, this.email.getMsg());
        }

        // ====================================================================
        // Test Exceptions
        // ====================================================================
        for (String invalidChar : testCharsNotValid)
        {
            try
            {
                this.email.setMsg(invalidChar);
                fail("Should have thrown an exception");
            }
            catch (EmailException e)
            {
                assertTrue(true);
            }
        }
    }

    /**
     * @throws EmailException when a bad address or attachment is used
     * @throws IOException when sending fails
     */
    @Test
    public void testSend() throws EmailException, IOException
    {
        // ====================================================================
        // Test Success
        // ====================================================================
        this.getMailServer();

        String strSubject = "Test Multipart Send Subject";

        EmailAttachment attachment = new EmailAttachment();
        attachment.setPath(testFile.getAbsolutePath());
        attachment.setDisposition(EmailAttachment.ATTACHMENT);
        attachment.setName("Test_Attachment");
        attachment.setDescription("Test Attachment Desc");

        MockMultiPartEmailConcrete testEmail =
            new MockMultiPartEmailConcrete();
        testEmail.setHostName(this.strTestMailServer);
        testEmail.setSmtpPort(this.getMailServerPort());
        testEmail.setFrom(this.strTestMailFrom);
        testEmail.addTo(this.strTestMailTo);
        testEmail.attach(attachment);
        testEmail.setSubType("subType");

        if (EmailUtils.isNotEmpty(this.strTestUser)
            && EmailUtils.isNotEmpty(this.strTestPasswd))
        {
            testEmail.setAuthentication(
                this.strTestUser,
                this.strTestPasswd);
        }

        testEmail.setSubject(strSubject);

        testEmail.setMsg("Test Message");

        Map<String, String> ht = new HashMap<String, String>();
        ht.put("X-Priority", "2");
        ht.put("Disposition-Notification-To", this.strTestMailFrom);
        ht.put("X-Mailer", "Sendmail");

        testEmail.setHeaders(ht);

        testEmail.send();

        this.fakeMailServer.stop();
        // validate message
        validateSend(
            this.fakeMailServer,
            strSubject,
            testEmail.getMsg(),
            testEmail.getFromAddress(),
            testEmail.getToAddresses(),
            testEmail.getCcAddresses(),
            testEmail.getBccAddresses(),
            true);

        // validate attachment
        validateSend(
            this.fakeMailServer,
            strSubject,
            attachment.getName(),
            testEmail.getFromAddress(),
            testEmail.getToAddresses(),
            testEmail.getCcAddresses(),
            testEmail.getBccAddresses(),
            false);

        // ====================================================================
        // Test Exceptions
        // ====================================================================
        try
        {
            this.getMailServer();

            this.email.send();
            fail("Should have thrown an exception");
        }
        catch (EmailException e)
        {
            this.fakeMailServer.stop();
        }
    }

    @Test
    public void testAttach() throws Exception
    {
        EmailAttachment attachment;

        // ====================================================================
        // Test Success - EmailAttachment
        // ====================================================================
        attachment = new EmailAttachment();
        attachment.setName("Test Attachment");
        attachment.setDescription("Test Attachment Desc");
        attachment.setPath(testFile.getAbsolutePath());
        this.email.attach(attachment);
        assertTrue(this.email.isBoolHasAttachments());

        // ====================================================================
        // Test Success - URL
        // ====================================================================
        attachment = new EmailAttachment();
        attachment.setName("Test Attachment");
        attachment.setDescription("Test Attachment Desc");
        attachment.setURL(new URL(this.strTestURL));
        this.email.attach(attachment);

        // ====================================================================
        // Test Success - File
        // ====================================================================
        this.email.attach(testFile);
        assertTrue(this.email.isBoolHasAttachments());

        // ====================================================================
        // Test Exceptions
        // ====================================================================
        // null attachment
        try
        {
            this.email.attach((EmailAttachment) null);
            fail("Should have thrown an exception");
        }
        catch (EmailException e)
        {
            assertTrue(true);
        }

        // bad url
        attachment = new EmailAttachment();
        try
        {
            attachment.setURL(createInvalidURL());
            this.email.attach(attachment);
            fail("Should have thrown an exception");
        }
        catch (EmailException e)
        {
            assertTrue(true);
        }

        // bad file
        attachment = new EmailAttachment();
        try
        {
            attachment.setPath("");
            this.email.attach(attachment);
            fail("Should have thrown an exception");
        }
        catch (EmailException e)
        {
            assertTrue(true);
        }
    }

    /**
     * @throws MalformedURLException when a bad attachment URL is used
     * @throws EmailException when a bad address or attachment is used
     */
    @Test
    public void testAttach2() throws MalformedURLException, EmailException
    {
        // ====================================================================
        // Test Success - URL
        // ====================================================================
        this.email.attach(
            new URL(this.strTestURL),
            "Test Attachment",
            "Test Attachment Desc");

        // bad name
        this.email.attach(
            new URL(this.strTestURL),
            null,
            "Test Attachment Desc");
    }

    @Test
    public void testAttach3() throws Exception
    {
        // ====================================================================
        // Test Success - URL
        // ====================================================================
        this.email.attach(
            new URLDataSource(new URL(this.strTestURL)),
            "Test Attachment",
            "Test Attachment Desc");

        // ====================================================================
        // Test Exceptions
        // ====================================================================
        // null datasource
        try
        {
            URLDataSource urlDs = null;
            this.email.attach(urlDs, "Test Attachment", "Test Attachment Desc");
            fail("Should have thrown an exception");
        }
        catch (EmailException e)
        {
            assertTrue(true);
        }

        // invalid datasource
        try
        {
            URLDataSource urlDs = new URLDataSource(createInvalidURL());
            this.email.attach(urlDs, "Test Attachment", "Test Attachment Desc");
            fail("Should have thrown an exception");
        }
        catch (EmailException e)
        {
            assertTrue(true);
        }
    }

    @Test
    public void testAttachFileLocking() throws Exception {

        // ====================================================================
        // EMAIL-120: attaching a FileDataSource may result in a locked file
        //            resource on windows systems
        // ====================================================================

        File tmpFile = File.createTempFile("attachment", ".eml");
        
        this.email.attach(
                new FileDataSource(tmpFile),
                "Test Attachment",
                "Test Attachment Desc");

        assertTrue(tmpFile.delete());
    }
    
    @Test
    public void testAddPart() throws Exception
    {

        // setup
        this.email = new MockMultiPartEmailConcrete();
        String strMessage = "hello";
        String strContentType = "text/plain";

        // add part
        this.email.addPart(strMessage, strContentType);

        // validate
        assertEquals(
            strContentType,
            this.email.getContainer().getBodyPart(0).getContentType());
        assertEquals(
            strMessage,
            this.email.getContainer().getBodyPart(0).getDataHandler()
                .getContent());

    }

    @Test
    public void testAddPart2() throws Exception
    {

        // setup
        this.email = new MockMultiPartEmailConcrete();
        String strSubtype = "subtype/abc123";

        // add part
        this.email.addPart(new MimeMultipart(strSubtype));

        // validate
        assertTrue(
            this
                .email
                .getContainer()
                .getBodyPart(0)
                .getDataHandler()
                .getContentType()
                .contains(strSubtype));

    }

    /** @todo implement test for GetContainer */
    @Test
    public void testGetContainer()
    {
        assertTrue(true);
    }

    /** init called twice should fail */
    @Test
    public void testInit()
    {
        // call the init function twice to trigger the IllegalStateException
        try
        {
            this.email.init();
            this.email.init();
            fail("Should have thrown an exception");
        }
        catch (IllegalStateException e)
        {
            assertTrue(true);
        }
    }

    /** test get/set sub type */
    @Test
    public void testGetSetSubType()
    {
        for (String validChar : testCharsValid)
        {
            this.email.setSubType(validChar);
            assertEquals(validChar, this.email.getSubType());
        }
    }
}
