/*
 * Tigase Jabber/XMPP Multi-User Chat Component
 * Copyright (C) 2008 "Bartosz M. Małkowski" <bartosz.malkowski@tigase.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. Look for COPYING file in the top folder.
 * If not, see http://www.gnu.org/licenses/.
 *
 * $Rev$
 * Last modified by $Author$
 * $Date$
 */
package tigase.muc.modules;

import java.util.Collection;

import tigase.component.exceptions.ComponentException;
import tigase.criteria.Criteria;
import tigase.muc.Role;
import tigase.muc.Room;
import tigase.muc.exceptions.MUCException;
import tigase.server.Packet;
import tigase.util.TigaseStringprepException;
import tigase.xml.Element;
import tigase.xmpp.Authorization;
import tigase.xmpp.BareJID;
import tigase.xmpp.JID;

/**
 * @author bmalkow
 * 
 */
public class IqStanzaForwarderModule extends AbstractMucModule {

	public static final String ID = "iqforwarder";

	private final Criteria crit = new Criteria() {

		@Override
		public Criteria add(Criteria criteria) {
			return null;
		}

		@Override
		public boolean match(Element element) {
			return checkIfProcessed(element);
		}
	};

	protected boolean checkIfProcessed(Element element) {
		if (element.getName() != "iq")
			return false;
		try {
			return getNicknameFromJid(JID.jidInstance(element.getAttributeStaticStr("to"))) != null;
		} catch (TigaseStringprepException e) {
			return false;
		}
	}

	@Override
	public String[] getFeatures() {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tigase.component.modules.Module#getModuleCriteria()
	 */
	@Override
	public Criteria getModuleCriteria() {
		return crit;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tigase.component.modules.Module#process(tigase.server.Packet)
	 */
	@Override
	public void process(Packet packet) throws ComponentException, TigaseStringprepException {
		try {
			final JID senderJID = packet.getStanzaFrom();
			final BareJID roomJID = packet.getStanzaTo().getBareJID();
			final String recipientNickname = getNicknameFromJid(packet.getStanzaTo());

			if (recipientNickname == null) {
				throw new MUCException(Authorization.BAD_REQUEST);
			}

			final Room room = context.getMucRepository().getRoom(roomJID);
			if (room == null) {
				throw new MUCException(Authorization.ITEM_NOT_FOUND);
			}

			final String senderNickname = getNicknameFromJid(senderJID);
			final Role senderRole = room.getRole(senderNickname);
			if (!senderRole.isSendPrivateMessages()) {
				throw new MUCException(Authorization.NOT_ALLOWED);
			}
			if (room.getOccupantsJidsByNickname(senderNickname).size() > 1)
				throw new MUCException(Authorization.NOT_ALLOWED, "Many source resources detected.");

			final Collection<JID> recipientJids = room.getOccupantsJidsByNickname(recipientNickname);
			if (recipientJids == null || recipientJids.isEmpty())
				throw new MUCException(Authorization.ITEM_NOT_FOUND, "Unknown recipient");

			if (recipientJids.size() > 1)
				throw new MUCException(Authorization.NOT_ALLOWED, "Many destination resources detected.");

			JID recipientJid = recipientJids.iterator().next();

			final Element iq = packet.getElement().clone();
			iq.setAttribute("from", roomJID.toString() + "/" + senderNickname);
			iq.setAttribute("to", recipientJid.toString());

			Packet p = Packet.packetInstance(iq);
			p.setXMLNS(Packet.CLIENT_XMLNS);
			write(p);
		} catch (MUCException e1) {
			throw e1;
		} catch (TigaseStringprepException e) {
			throw new MUCException(Authorization.BAD_REQUEST);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

}

@@ -863,28 +863,115 @@
 ort 
-java.util.Collection
+tigase.server.Packet;%0A%0Aimport tigase.xmpp.Authorization;%0Aimport tigase.xmpp.BareJID;%0Aimport tigase.xmpp.JID
 ;%0A%0Ai
@@ -1152,37 +1152,8 @@
 on;%0A
-import tigase.server.Packet;%0A
 impo
@@ -1225,92 +1225,68 @@
 nt;%0A
+%0A
 import 
-tigase.xmpp.Authorization;%0Aimport tigase.xmpp.BareJID;%0Aimport tigase.xmpp.JID
+java.util.Collection;%0Aimport java.util.logging.Level
 ;%0A%0A/
@@ -2875,35 +2875,43 @@
 kname = 
-getNicknameFromJid(
+room.getOccupantsNickname( 
 senderJI
@@ -2911,16 +2911,17 @@
 enderJID
+ 
 );%0A%09%09%09fi
@@ -2968,24 +2968,307 @@
 rNickname);%0A
+%0A%09%09%09if ( log.isLoggable( Level.FINEST ) )%7B%0A%09%09%09%09log.log( Level.FINEST,%0A%09%09%09%09%09%09 %22Processing IQ stanza, from: %7B0%7D, to: %7B1%7D, recipientNickname: %7B2%7D, senderNickname: %7B3%7D, senderRole: %7B4%7D %22,%0A%09%09%09%09%09%09 new Object%5B%5D %7B senderJID, roomJID, recipientNickname, senderNickname, senderRole %7D );%0A%09%09%09%7D%0A%0A
 %09%09%09if (!send
@@ -3353,16 +3353,64 @@
 _ALLOWED
+, %22Role is not allowed to send private messages%22
 );%0A%09%09%09%7D%0A

fix issue with retrieving nickname/role of the sender user in IqStanzaForwarderModule; #2221