/*
 * IRCMessageTest.java
 * IRCCoreTest
 *
 * Created by tarchan on Nov 25, 2006.
 * Copyright (c) 2006 tarchan. All rights reserved.
 */
package com.mac.tarchan.irc;

import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Date;

import junit.framework.TestCase;

import com.mac.tarchan.irc.IRCMessage;

/**
 * IRCMessageTest
 *
 * @author tarchan
 */
public class IRCMessageTest extends TestCase
{
	public void testPingCommand()
	{
		IRCMessage msg = new IRCMessage(this, "PING :irc.huie.hokudai.ac.jp");
		String cmd = msg.getCommand();
		assertEquals(null, msg.getTarget());
		assertEquals("PING", cmd);
	}

	public void testPingTrail()
	{
		IRCMessage msg = new IRCMessage(this, "PING :irc.huie.hokudai.ac.jp");
		String trail = msg.getTrailing();
		assertEquals(null, msg.getTarget());
		assertEquals("irc.huie.hokudai.ac.jp", trail);
	}

	public void test001Command()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.tokyo.wide.ad.jp 001 tarc2 :Welcome to the Internet Relay Network tarc2!~tarchan@221x254x0x9.ap221.ftth.ucom.ne.jp");
		String cmd = msg.getCommand();
		assertEquals("tarc2", msg.getTarget());
		assertEquals("001", cmd);
	}

	public void test001Trail()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.tokyo.wide.ad.jp 001 tarc2 :Welcome to the Internet Relay Network");
		String trail = msg.getTrailing();
		assertEquals("tarc2", msg.getTarget());
		assertEquals("Welcome to the Internet Relay Network", trail);
	}

	public void test001IsNumelic()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.tokyo.wide.ad.jp 001 tarc2 :Welcome to the Internet Relay Network");
		assertEquals("tarc2", msg.getTarget());
		assertEquals(true, msg.isNumelic());
	}

	public void test001NotNumelic1()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.tokyo.wide.ad.jp 1 tarc2 :Welcome to the Internet Relay Network");
		assertEquals("tarc2", msg.getTarget());
		assertEquals(false, msg.isNumelic());
	}

	public void test001NotNumelic01()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.tokyo.wide.ad.jp 01 tarc2 :Welcome to the Internet Relay Network");
		assertEquals("tarc2", msg.getTarget());
		assertEquals(false, msg.isNumelic());
	}

	public void test001NotNumelic01a()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.tokyo.wide.ad.jp 01a tarc2 :Welcome to the Internet Relay Network");
		assertEquals("tarc2", msg.getTarget());
		assertEquals(false, msg.isNumelic());
	}

	public void test001NotNumelicWEL()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.tokyo.wide.ad.jp WEL tarc2 :Welcome to the Internet Relay Network");
		assertEquals("tarc2", msg.getTarget());
		assertEquals(false, msg.isNumelic());
	}

	public void testModeNick()
	{
		IRCMessage msg = new IRCMessage(this, ":tarc2 MODE tarc2 :+iw");
		String nick = msg.getTarget();
		assertEquals("tarc2", msg.getTarget());
		assertEquals("tarc2", nick);
	}

	public void testModeServerMode()
	{
		IRCMessage msg = new IRCMessage(this, ":tarc2 MODE tarc2 :+iw");
		String nick = msg.getNick();
		String channel = msg.getTarget();
		String mode = msg.getTrailing();
		assertEquals("tarc2", nick);
		assertEquals("tarc2", channel);
		assertEquals("+iw", mode);
	}

	public void testModeChannelMode()
	{
		IRCMessage msg = new IRCMessage(this, ":MALINO_!~username@210-20-162-17.rev.home.ne.jp MODE #irodorie:*.jp +ooo ai-dead ging_ iroha");
		String mode = msg.getParam(1);
		assertEquals("#irodorie:*.jp", msg.getTarget());
		assertEquals("+ooo", mode);
	}

	public void testModeUserList()
	{
		IRCMessage msg = new IRCMessage(this, ":MALINO_!~username@210-20-162-17.rev.home.ne.jp MODE #irodorie:*.jp +ooo ai-dead ging_ iroha");
		String[] list = msg.getParams(2);
		assertEquals("#irodorie:*.jp", msg.getTarget());
		assertEquals("ai-dead", list[0]);
	}

	public void testJoinNick()
	{
		IRCMessage msg = new IRCMessage(this, ":tarc2!~tarchan@221x254x0x23.ap221.ftth.ucom.ne.jp JOIN :#irodorie:*.jp");
		String nick = msg.getNick();
//		String user = msg.getUser();
//		String host = msg.getHost();
//		String channel = msg.getTrailing();
		assertEquals("tarc2", nick);
//		assertEquals("~tarchan", user);
//		assertEquals("221x254x0x23.ap221.ftth.ucom.ne.jp", host);
//		assertEquals("#irodorie:*.jp", channel);
	}

	public void testJoinUser()
	{
		IRCMessage msg = new IRCMessage(this, ":tarc2!~tarchan@221x254x0x23.ap221.ftth.ucom.ne.jp JOIN :#irodorie:*.jp");
		String user = msg.getUser();
		assertEquals(null, msg.getTarget());
		assertEquals("~tarchan", user);
	}

	public void testJoinHost()
	{
		IRCMessage msg = new IRCMessage(this, ":tarc2!~tarchan@221x254x0x23.ap221.ftth.ucom.ne.jp JOIN :#irodorie:*.jp");
		String host = msg.getHost();
		assertEquals(null, msg.getTarget());
		assertEquals("221x254x0x23.ap221.ftth.ucom.ne.jp", host);
	}

	public void testJoinChannel()
	{
		IRCMessage msg = new IRCMessage(this, ":tarc2!~tarchan@221x254x0x23.ap221.ftth.ucom.ne.jp JOIN :#irodorie:*.jp");
		String ch = msg.getTrailing();
		assertEquals(null, msg.getTarget());
		assertEquals("#irodorie:*.jp", ch);
	}

	public void testNickOldNick()
	{
		IRCMessage msg = new IRCMessage(this, ":tarc2!~tarchan@221x254x0x10.ap221.ftth.ucom.ne.jp NICK :tarcMLB");
		String oldNick = msg.getNick();
		assertEquals(null, msg.getTarget());
		assertEquals("tarc2", oldNick);
	}

	public void testNickNewNick()
	{
		IRCMessage msg = new IRCMessage(this, ":tarc2!~tarchan@221x254x0x10.ap221.ftth.ucom.ne.jp NICK :tarcMLB");
		String newNick = msg.getTrailing();
		assertEquals(null, msg.getTarget());
		assertEquals("tarcMLB", newNick);
	}

	public void test332Topic()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.huie.hokudai.ac.jp 332 tarc2 #dameTunes :http://plagger.org/trac/changeset/1236 $B$G=$@5$5$l$?$N$G!\":G?7HG$KDI?o$9$l$PD>$k(B");
		String topic = msg.getTrailing("iso2022jp");
		// topic = new String(topic.getBytes(), "iso-2022-jp");
		assertEquals("tarc2", msg.getTarget());
		assertEquals("http://plagger.org/trac/changeset/1236 で修正されたので、最新版に追随すれば直る", topic);
	}

	public void test332Channel()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.huie.hokudai.ac.jp 332 tarc2 #dameTunes :http://plagger.org/trac/changeset/1236 $B$G=$@5$5$l$?$N$G!\":G?7HG$KDI?o$9$l$PD>$k(B");
		String ch = msg.getParam(1);
		assertEquals("tarc2", msg.getTarget());
		assertEquals("#dameTunes", ch);
	}

	public void test333Nick()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.huie.hokudai.ac.jp 333 tarc2 #dameTunes Kaho!~Kaho@namesv1.solar.or.jp 1155092809");
		String who = msg.getMessageSource();
		String[] addr = who.split(IRCMessage.ADDRESS_DELIMITER);
		// System.out.println("list=" + Arrays.asList(addr));
		String nick = addr[0];
		assertEquals("tarc2", msg.getTarget());
		assertEquals("Kaho", nick);
	}

	public void test333Time()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.huie.hokudai.ac.jp 333 tarc2 #dameTunes Kaho!~Kaho@namesv1.solar.or.jp 1155092809");
		String sec = msg.getParam(3);
		Date time = new Date(Long.parseLong(sec) * 1000);
		MessageFormat format = new MessageFormat("{0,date,yyyyMMdd}");
		assertEquals("tarc2", msg.getTarget());
		assertEquals("20060809", format.format(new Object[]{time}));
	}

	public void test353Names()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.huie.hokudai.ac.jp 353 tarc2 @ #dameTunes :@matuken @Kaho @m_mai hideo masan_Zzz ");
		String[] names = msg.getTrailing().split(" ");
		assertEquals("tarc2", msg.getTarget());
		assertEquals("@matuken", names[0]);
	}

	public void test366Target()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.huie.hokudai.ac.jp 366 tarc2 #dameTunes :End of NAMES list.");
		String target = msg.getMessageTarget();
		assertEquals("#dameTunes", target);
	}

	public void testQuitNick()
	{
		IRCMessage msg = new IRCMessage(this, ":E03!~E03@jo1.opt2.point.ne.jp QUIT :\"Leaving..\"");
		String nick = msg.getNick();
		String cause = msg.getTrailing("iso2022jp");
		assertEquals("E03", nick);
		assertEquals("\"Leaving..\"", cause);
	}

	public void testQuitMessage()
	{
		IRCMessage msg = new IRCMessage(this, ":E03!~E03@jo1.opt2.point.ne.jp QUIT :\"Leaving..\"");
		String trail = msg.getTrailing("iso2022jp");
		assertEquals(null, msg.getTarget());
		assertEquals("\"Leaving..\"", trail);
	}

	public void testPrivmsgNick()
	{
		IRCMessage msg = new IRCMessage( this, ":kyokorin!~Nihondo@241.73.30.125.dy.iij4u.or.jp PRIVMSG #dameTunes :$B:#F|$b%+%l!<$r?)$Y$F$7$^$$$^$7$?(B");
		String nick = msg.getNick();
		assertEquals("#dameTunes", msg.getTarget());
		assertEquals("kyokorin", nick);
	}

	public void testPrivmsgShortNick()
	{
		IRCMessage msg = new IRCMessage( this, ":kyokorin PRIVMSG #dameTunes :$B:#F|$b%+%l!<$r?)$Y$F$7$^$$$^$7$?(B");
		String nick = msg.getNick();
		assertEquals("#dameTunes", msg.getTarget());
		assertEquals("kyokorin", nick);
	}

	public void testPrivmsgMessage()
	{
		IRCMessage msg = new IRCMessage( this, ":kyokorin!~Nihondo@241.73.30.125.dy.iij4u.or.jp PRIVMSG #dameTunes :$B:#F|$b%+%l!<$r?)$Y$F$7$^$$$^$7$?(B");
		String trail = msg.getTrailing("iso2022jp");
		assertEquals("#dameTunes", msg.getTarget());
		assertEquals("今日もカレーを食べてしまいました", trail);
	}

//	public void testPrivmsgMessageSJIS()
//	{
//		IRCMessage msg = new IRCMessage( this, ":kyokorin!~Nihondo@241.73.30.125.dy.iij4u.or.jp PRIVMSG #dameTunes :00:02:14 <%irodorie:kamiyoshi> (Jﾃﾍ(B");
//		String trail = msg.getTrailing("shift_jis");
//		assertEquals("今日もカレーを食べてしまいました", trail);
//	}

//	public void testPrivmsgMessageHankaku()
//	{
//		String encode = IRCMessage.encode("俺の股間にｽﾌﾟﾘﾝｸﾞﾊｽﾞｶﾑ", "iso2022jp");
//		assertEquals("俺の股間にｽﾌﾟﾘﾝｸﾞﾊｽﾞｶﾑ", IRCMessage.decode(encode, "iso2022jp"));
//	}

	public void testPrivmsgURL()
	{
		IRCMessage msg = new IRCMessage(
				this,
				":dameNews!~dameNews@i207131.ppp.asahi-net.or.jp PRIVMSG #dameTunes :$B$o$+$P(B $B99?7(B http://wakaba.to/~wakaba/d/?08260817");
		String trail = msg.getTrailing("iso2022jp");
		int index = trail.indexOf("http:");
		String url = null;
		if (index >= 0)
		{
			url = trail.substring(index);
		}
		assertEquals("http://wakaba.to/~wakaba/d/?08260817", url);
	}

	public void testNoticeMessage()
	{
		IRCMessage msg = new IRCMessage(
				this,
				":yuta_TKH!~yuta@ntkngw210134.kngw.nt.ftth.ppp.infoweb.ne.jp NOTICE #dameTunes :Eisuke@: $B$=$N8e(B - http://e-atmark.net/archives/2006/08/post_2069.html by Eisuke");
		String trail = msg.getTrailing("iso2022jp");
		assertEquals(
				"Eisuke@: その後 - http://e-atmark.net/archives/2006/08/post_2069.html by Eisuke",
				trail);
	}

	public void testNoticeMadokaTail()
	{
		IRCMessage msg = new IRCMessage(
				this,
				"NOTICE tarcTOP2 :Tail: 01:08:28 <%irodorie:shibaF1> $B$1$C$3$&$\"$k$s$G$9$h(B");
		String trail = msg.getTrailing("iso2022jp");
		// parse madoka log
		assertEquals("Tail: 01:08:28 <%irodorie:shibaF1> けっこうあるんですよ", trail);
	}

	public void testWhoisNick()
	{
		IRCMessage msg = new IRCMessage(
				this,
				":irc.huie.hokudai.ac.jp 311 tarc2 tarcMLB ~tarchan 221x254x0x10.ap221.ftth.ucom.ne.jp * :たーちゃん");
		String nick = msg.getMessageTarget();
		assertEquals("tarcMLB", nick);
	}

	public void testWhoisChannel()
	{
		IRCMessage msg = new IRCMessage(
				this,
				":irc.huie.hokudai.ac.jp 319 tarc2 tarcMLB :@#dameTunes @#irodorie:*.jp @#javabreak ");
		String trail = msg.getTrailing();
		String[] ch = trail.split(" ");
		assertEquals("@#irodorie:*.jp", ch[1]);
	}

	public void testWhoisServer()
	{
		IRCMessage msg = new IRCMessage(
				this,
				":irc.huie.hokudai.ac.jp 312 tarc2 tarcMLB irc.tokyo.wide.ad.jp :WIDE Project Tokyo NOC, Japan");
		String server = msg.getMessageSource();
		assertEquals("irc.tokyo.wide.ad.jp", server);
	}

	public void testWhoisEnd()
	{
		IRCMessage msg = new IRCMessage(this,
				":irc.huie.hokudai.ac.jp 318 tarc2 tarcMLB :End of WHOIS list.");
		String cmd = msg.getCommand();
		assertEquals("318", cmd);
	}

	public void testErrorCommand()
	{
		IRCMessage msg = new IRCMessage(this, "ERROR: Closing Link: tarchan");
//		IRCMessage msg = new IRCMessage(this, "ERROR :Closing Link: tarchan");
		String cmd = msg.getCommand();
		assertEquals("ERROR", cmd);
	}

	public void testErrorTrail()
	{
		IRCMessage msg = new IRCMessage(this, "ERROR: Closing Link: tarchan");
		String trail = msg.getTrailing();
		assertEquals("Closing Link: tarchan", trail);
	}

	public void testCtcp001()
	{
		String input = ":Alice PRIVMSG #channel :\1ACTION said hello\1";
		IRCMessage msg = new IRCMessage(this, input);
//		String[] token = msg.getTrailing().split("\001");
//		String[] token = IRCMessage.toCTCP(msg.getTrailing("ISO-2022-JP"));
		String[] token = IRCMessage.splitCTCP(msg.getTrailing("ISO-2022-JP"));
//		input = msg.getTrailing("ISO-2022-JP");
////		input = msg.getTrailing();
		int index = input.indexOf("\1");
		System.out.println("ctcp=" + Arrays.asList(token) + "," + index);
		assertEquals("ACTION said hello", token[1]);
	}

	public void testCtcp002()
	{
		String input = ":Alice PRIVMSG #channel :\1ACTION said hello";
		IRCMessage msg = new IRCMessage(this, input);
		String[] token = IRCMessage.splitCTCP(msg.getTrailing("ISO-2022-JP"));
		System.out.println("ctcp=" + Arrays.asList(token));
		assertEquals("ACTION said hello", token[1]);
	}

	public void testCtcp003()
	{
		String input = ":Alice PRIVMSG #channel :ACTION said hello";
		IRCMessage msg = new IRCMessage(this, input);
		String[] token = IRCMessage.splitCTCP(msg.getTrailing("ISO-2022-JP"));
		System.out.println("ctcp=" + Arrays.asList(token));
		assertEquals("ACTION said hello", token[0]);
	}

	public void testCtcp004()
	{
		String input = ":Alice PRIVMSG #channel :\1A\1B\1C\1";
		IRCMessage msg = new IRCMessage(this, input);
		String[] token = IRCMessage.splitCTCP(msg.getTrailing("ISO-2022-JP"));
		System.out.println("ctcp=" + Arrays.asList(token));
		assertEquals("C", token[3]);
	}

	public void testFormat001()
	{
		IRCMessage msg = new IRCMessage(this, ":irc.tokyo.wide.ad.jp 001 tarc2 :Welcome to the Internet Relay Network tarc2!~tarchan@221x254x0x9.ap221.ftth.ucom.ne.jp");
		System.err.format("msg=%st,%<s2\n", msg);
	}

	public void testTail001()
	{
		String input = "NOTICE tarcNEW :Tail: 19:25:36 <#dameTunes:Kaho> diffをBBSにコピペでどうか";
//		String input = "NOTICE tarcNEW :Tail: 19:25:52 [!] Connect: 221.254.0.9(39608)/25";
		IRCMessage msg = new IRCMessage(this, input);
		String trail = msg.getTrailing();
		MessageFormat tailForm = new MessageFormat("Tail: {0} <{1}:{2}> {3}");
		try
		{
			Object[] objs = tailForm.parse(trail);
			System.out.println("objs=" + Arrays.asList(objs));
			DateFormat timeForm = DateFormat.getTimeInstance();
			Date time = timeForm.parse(objs[0].toString());
			System.out.println("time=" + time);
			IRCMessage msg2 = new IRCMessage(this, "TAIL #dameTunes");
			String target = msg2.getTarget();
			System.out.println("target=" + target);
		}
		catch (ParseException x)
		{
			x.printStackTrace();
		}
	}

	public void testKana001()
	{
//		String input = "08:39:57 <%irodorie:GORO_> $BBfOQ@=$N0BJ*$@$+$i%3%T%o%s?.9fL5;k$7$F$/$l$J$$$+$J$"(B($B!-&X(B`)$B$H$+;W$C$?$1$I(B";
//		String trail = IRCMessage.decode(input, "ISO-2022-JP");
//		System.out.println("trail=" + trail);
//		assertEquals("ACTION said hello", trail);
	}
}
