/**
 * parser.cpp (2007-05-13)
 *
 * -- CABAL -- irc commands parser
 *
 * Copyright (c) 2007, NOD Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *	* Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 *	* Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in the
 *	  documentation and/or other materials provided with the distribution.
 *	* Neither the name of the NOD Team nor the names of its contributors
 *	  may be used to endorse or promote products derived from this
 *	  software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "cabal.h"	// required: parser.h

Parser::Parser (Connection *S, string parsing) : alien (""), alienid (""), \
	alienact (""), alienloc (""), aliencmd (""), alienmsg ("")
{
	if (parsing.substr (0, 6) == "PING :")
	{
		string pong = parsing;
		pong[1] = 'O';
		S->msgSend (pong);
	}
	else
	{
		char *query = new char[parsing.size() + 1];

		int e = 0;

		while ((query[e] = parsing[e]))
			e++;

		char *who = new char[e];
		char *what = new char[e];
		char *where = new char[e];
		char *message = new char[e];

		if (sscanf (query, "%s %s %s", who, what, where) == 3)
		{
			alienact = what;

			if ((alienid = strchr (who, '!')))
			{
				alienid++, alien = strtok (who, "!");

				if (*where == ':')
					alienloc = where + 1;
				else
				{
					alienloc = where;

					if ((aliencmd = strchr (strstr (query, alienloc), ' ')) \
						&& *++aliencmd == ':')
					{
						if (!strcmp (alienloc, S->nick))
							alienloc = alien;

						if (*++aliencmd == CABAL->cmdc)
						{
							if ((alienmsg = strchr (aliencmd, ' ')))
								alienmsg++;
							else
								alienmsg = "";

							aliencmd = strtok (aliencmd, " "), aliencmd++;
						}
						else
							alienmsg = aliencmd, aliencmd = "";
					}
					else
						alienmsg = strtok (aliencmd, " "), aliencmd = "";
				}
			}
			else
				alienid = "";
/* DEBUG
			cout
				<< "-----------------------------------\n" \
				<< "Alien:	\t" << alien << endl \
				<< "Alien ID:\t" << alienid << endl \
				<< "Alien action:\t" << alienact << endl \
				<< "Alien location:\t" << alienloc << endl \
				<< "Alien command:\t" << aliencmd << endl \
				<< "Alien message:\t" << alienmsg << endl \
				<< "-----------------------------------\n";
*/		}

		delete[] who;
		delete[] what;
		delete[] where;
		delete[] message;
		delete[] query;
	}
}

Parser::~Parser()
{
	alien = alienid = alienact = alienloc = aliencmd = alienmsg = "";
}

void Parser::Parse (Connection *S)
{
	if (!strcmp (aliencmd, "die") && !strcmp (alienid, "stealth@ru.raver"))
		shut ("Requested shutdown");

	if (!strcmp (aliencmd, "hi"))
		S->msgSend ("PRIVMSG " + (string)alienloc + " :" + "Hello, " + \
			(string)alien + " (" + (string)alienid + ")");

	if (!strcmp (aliencmd, "nick"))
		S->ircNick (alienmsg);

	if (!strcmp (aliencmd, "away"))
		S->ircAway (alienmsg);

	if (!strcmp (aliencmd, "join"))
		S->ircJoin (alienmsg, "");

	if (!strcmp (aliencmd, "part"))
		S->ircPart (alienmsg);

	if (!strcmp (aliencmd, "cycle") && strcmp (alienloc, S->nick))
		S->ircCycle (alienloc);

	if (!strcmp (aliencmd, "uptime"))
		S->msgSend ("PRIVMSG " + (string)alienloc + " :Online since: " + \
			(string)eTime (S->uptime));

	if (!strcmp (aliencmd, "country"))
		S->msgSend ("PRIVMSG " + (string)alienloc + " :" + \
			(string)eCountry (alienmsg));

// Autorejoin
	if (!strcmp (alienact, "KICK") && !strcmp (alienmsg, S->nick))
		S->ircJoin (alienloc, "");
}
