/**
 * $Revision $
 * $Date $
 *
 * Copyright (C) 2005-2010 Jive Software. All rights reserved.
 *
 * Licensed 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.jinglenodes;

import org.dom4j.Element;
import org.jivesoftware.openfire.XMPPServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.component.AbstractComponent;
import org.xmpp.jnodes.RelayChannel;
import org.xmpp.jnodes.nio.LocalIPResolver;
import org.xmpp.jnodes.smack.JingleChannelIQ;
import org.xmpp.packet.IQ;
import org.xmpp.packet.PacketError;

class JingleNodesComponent extends AbstractComponent {
	private static final Logger Log = LoggerFactory.getLogger(JingleNodesComponent.class);

	private static final String UDP = "udp";
	private static final String PROTOCOL = "protocol";
	private static final String HOST = "host";
	private static final String LOCAL_PORT = "localport";
	private static final String REMOTE_PORT = "remoteport";

	private final JingleNodesPlugin plugin;

	public JingleNodesComponent(final JingleNodesPlugin plugin) {
		this.plugin = plugin;
	}

	public String getName() {
		return "JingleRelayNode";
	}

	public String getDescription() {
		return "Jingle Relay Service";
	}

	@Override
	protected String[] discoInfoFeatureNamespaces() {
		return new String[] { JingleChannelIQ.NAMESPACE };
	}

	@Override
	protected String discoInfoIdentityCategoryType() {
		return "relay";
	}

	@Override
	protected IQ handleIQGet(IQ iq) throws Exception {
		final IQ reply = IQ.createResultIQ(iq);

		final Element element = iq.getChildElement();
		final String namespace = element.getNamespaceURI();

		if (JingleChannelIQ.NAME.equals(element.getName()) && JingleChannelIQ.NAMESPACE.equals(namespace)
				&& UDP.equals(element.attributeValue(PROTOCOL))) {
			final Element childElement = iq.getChildElement().createCopy();
			final RelayChannel channel = plugin.createRelayChannel();

			if (channel != null) {
				childElement.addAttribute(HOST, LocalIPResolver.getLocalIP());
				childElement.addAttribute(LOCAL_PORT, Integer.toString(channel.getPortA()));
				childElement.addAttribute(REMOTE_PORT, Integer.toString(channel.getPortB()));
				reply.setChildElement(childElement);
				
				Log.debug("Created relay channel {}:{}, {}:{}, {}:{}", new Object[] { HOST,
						LocalIPResolver.getLocalIP(), LOCAL_PORT, Integer.toString(channel.getPortA()), REMOTE_PORT,
						Integer.toString(channel.getPortB()) });

			} else {
				reply.setError(PacketError.Condition.internal_server_error);
			}
			return reply;
		}

		return null; // feature not implemented.
	}

	@Override
	public String getDomain() {
		return XMPPServer.getInstance().getServerInfo().getXMPPDomain();
	}
}
