package com.ozacc.mail.impl;

import java.io.UnsupportedEncodingException;
import java.util.Iterator;

import javax.mail.internet.MimeUtility;

import junit.framework.TestCase;

import org.apache.log4j.BasicConfigurator;

import com.dumbster.smtp.SimpleSmtpServer;
import com.dumbster.smtp.SmtpMessage;
import com.ozacc.mail.Mail;
import com.ozacc.mail.MailException;

/**
 * SendMailImplクラスのテストケース。
 * <p>
 * Dumbsterを使用してテストしているが、サポートされていない機能が多い。
 * 
 * @author Tomohiro Otsuka
 * @version $Id: SendMailImplTest.java,v 1.3 2004/09/14 00:06:13 otsuka Exp $
 */
public class SendMailImplTest extends TestCase {

	private SendMailImpl sendMail;

	private SimpleSmtpServer server;

	/*
	 * @see TestCase#setUp()
	 */
	protected void setUp() throws Exception {
		super.setUp();

		BasicConfigurator.configure();

		int port = 2525;
		server = SimpleSmtpServer.start(port);
		sendMail = new SendMailImpl();
		sendMail.setPort(port);
	}

	/**
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {
		BasicConfigurator.resetConfiguration();
	}

	private String convertJisValue(String str) throws UnsupportedEncodingException {
		return new String(str.getBytes(), "JIS");
	}

	/**
	 * 単発メールのテスト。
	 * 
	 * @throws Exception
	 */
	public void testSendMail() throws Exception {
		String from = "from@example.com";
		String fromName = "差出人";
		String to = "info@example.com";
		String subject = "件名";
		String text = "テスト成功";

		Mail mail = new Mail();
		mail.setFrom(from, fromName);
		mail.addTo(to);
		mail.setSubject(subject);
		mail.setText(text);

		sendMail.send(mail);

		server.stop();

		assertEquals("1", 1, server.getReceievedEmailSize());
		Iterator inbox = server.getReceivedEmail();
		SmtpMessage email = (SmtpMessage)inbox.next();

		assertEquals("2", mail.getTo()[0].toString(), email.getHeaderValue("To"));
		assertEquals("3", mail.getFrom().toString(), email.getHeaderValue("From"));

		assertEquals("4", mail.getSubject(), MimeUtility
				.decodeText(email.getHeaderValue("Subject")));
		assertEquals("5", mail.getText() + "\n", convertJisValue(email.getBody()));
	}

	/**
	 * 複数メールの一括送信テスト。
	 * 同一接続内の複数メッセージを送信するとDumbsterがエラーを吐くので、
	 * とりあえず1つのMailインスタンスの配列でテスト。
	 * 実際のSMTPサーバ(qmail)で正常に送信できることは確認済み。
	 * 
	 * @throws Exception
	 */
	public void testSendMailMultiple() throws Exception {
		String from = "from@example.com";
		String fromName = "差出人";
		String to = "info@example.com";
		String subject = "件名";
		String text = "テスト成功";

		Mail mail1 = new Mail();
		mail1.setFrom(from, fromName);
		mail1.addTo(to);
		mail1.setSubject(subject);
		mail1.setText(text);

		Mail mail2 = new Mail();
		mail2.setFrom(from, fromName);
		mail2.addTo(to);
		mail2.setSubject(subject);
		mail2.setText(text);

		Mail mail3 = new Mail();
		mail3.setFrom(from, fromName);
		mail3.addTo(to);
		mail3.setSubject(subject);
		mail3.setText(text);

		// Dumbsterのバグが直ったら、mail1, mail2, mail3 を含めてテスト
		sendMail.send(new Mail[] { mail1 });

		server.stop();

		// Dumbsterのバグが直ったら、3 に。
		assertEquals("1", 1, server.getReceievedEmailSize());

		Iterator inbox = server.getReceivedEmail();
		SmtpMessage email = (SmtpMessage)inbox.next();

		assertEquals("2", mail1.getTo()[0].toString(), email.getHeaderValue("To"));
		assertEquals("3", mail1.getFrom().toString(), email.getHeaderValue("From"));

		assertEquals("4", mail1.getSubject(), MimeUtility.decodeText(email
				.getHeaderValue("Subject")));
		assertEquals("5", mail1.getText() + "\n", convertJisValue(email.getBody()));
	}

	public void testSendMailWithReturnPath() throws Exception {
		String from = "from@example.com";
		String fromName = "差出人";
		String to = "info@example.com";
		String subject = "件名";
		String text = "テスト成功";
		String returnPath = "return-path@example.com";

		Mail mail = new Mail();
		mail.setFrom(from, fromName);
		mail.addTo(to);
		mail.setSubject(subject);
		mail.setText(text);
		mail.setReturnPath(returnPath);
		mail.setImportance(Mail.Importance.HIGH);

		sendMail.send(mail);

		server.stop();

		assertEquals(1, server.getReceievedEmailSize());
		Iterator inbox = server.getReceivedEmail();
		SmtpMessage email = (SmtpMessage)inbox.next();

		// ヘッダー出力
		/*
		 Iterator itr = email.getHeaderNames();
		 while (itr.hasNext()) {
		 String name = (String)itr.next();
		 System.out.println(name + "='" + email.getHeaderValue(name) + "'");
		 }
		 */

		// Dumbsterでは、Return-Pathヘッダを保持していない
		//assertEquals(mail.getReturnPath().toString(), email.getHeaderValue("Return-Path"));
		// 重要度を確認
		assertEquals(mail.getImportance(), email.getHeaderValue("Importance"));
		assertEquals("1", email.getHeaderValue("X-Priority"));
	}

	/**
	 * 宛先を一件も指定していないためsend()時に例外をスロー。
	 * To、Cc、Bccを一件でも指定すれば、この例外は起こらない。
	 * 
	 * @throws Exception
	 */
	public void testSendMailNoRecpient() throws Exception {
		String from = "from@example.com";
		String fromName = "差出人";
		String subject = "件名";
		String text = "テスト成功";

		Mail mail = new Mail();
		mail.setFrom(from, fromName);
		mail.setSubject(subject);
		mail.setText(text);

		try {
			sendMail.send(mail);
			fail("This should never be called.");
		} catch (MailException expected) {
			assertEquals("MimeMessageの生成に失敗しました。", expected.getMessage());
		}
	}

}