/*******************************************************************************
 * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: Composent, Inc. - initial API and implementation
 ******************************************************************************/
package org.eclipse.ecf.internal.provider.xmpp.smack;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.ecf.core.ContainerAuthenticationException;
import org.eclipse.ecf.core.ContainerConnectException;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.identity.Namespace;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.internal.provider.xmpp.XmppPlugin;
import org.eclipse.ecf.provider.comm.DisconnectEvent;
import org.eclipse.ecf.provider.comm.IAsynchEventHandler;
import org.eclipse.ecf.provider.comm.IConnectionListener;
import org.eclipse.ecf.provider.comm.ISynchAsynchConnection;
import org.eclipse.ecf.provider.xmpp.identity.XMPPID;
import org.eclipse.ecf.provider.xmpp.identity.XMPPRoomID;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.SSLXMPPConnection;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Message.Type;

public class ECFConnection implements ISynchAsynchConnection {

	/**
	 * 
	 */
	private static final String GOOGLE_TALK_HOST = "talk.google.com";
	public static final String CLIENT_TYPE = "ECF_XMPP";
	public static final boolean DEBUG = Boolean.getBoolean(System.getProperty("smack.debug", "false"));

	protected static final String STRING_ENCODING = "UTF-8";
	public static final String OBJECT_PROPERTY_NAME = ECFConnection.class.getName() + ".object";
	protected static final int XMPP_DEFAULT_PORT = 5222;
	protected static final int XMPPS_DEFAULT_PORT = 5223;

	private XMPPConnection connection = null;
	private IAsynchEventHandler handler = null;
	private boolean isStarted = false;
	private String serverName;
	private int serverPort = -1;
	private final Map properties = null;
	private boolean isConnected = false;
	private Namespace namespace = null;

	private boolean google = false;

	private boolean secure = false;

	private boolean disconnecting = false;

	private final PacketListener packetListener = new PacketListener() {
		public void processPacket(Packet arg0) {
			handlePacket(arg0);
		}
	};

	private final ConnectionListener connectionListener = new ConnectionListener() {
		public void connectionClosed() {
			handleConnectionClosed(new IOException("Connection reset by peer"));
		}

		public void connectionClosedOnError(Exception e) {
			handleConnectionClosed(e);
		}
	};

	protected void logException(String msg, Throwable t) {
		XmppPlugin.log(msg, t);
	}

	public Map getProperties() {
		return properties;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class adapter) {
		if (adapter == null)
			return null;
		if (adapter.isInstance(this))
			return this;
		final IAdapterManager adapterManager = XmppPlugin.getDefault().getAdapterManager();
		return (adapterManager == null) ? null : adapterManager.loadAdapter(this, adapter.getName());
	}

	public XMPPConnection getXMPPConnection() {
		return connection;
	}

	public ECFConnection(boolean google, Namespace ns, IAsynchEventHandler h, boolean secure) {
		this.handler = h;
		this.namespace = ns;
		this.google = google;
		this.secure = secure;
	}

	public ECFConnection(boolean google, Namespace ns, IAsynchEventHandler h) {
		this(google, ns, h, false);
	}

	protected String getPasswordForObject(Object data) {
		String password = null;
		try {
			password = (String) data;
		} catch (final ClassCastException e) {
			return null;
		}
		return password;
	}

	private XMPPID getXMPPID(ID remote) throws ECFException {
		XMPPID jabberID = null;
		try {
			jabberID = (XMPPID) remote;
		} catch (final ClassCastException e) {
			throw new ECFException(e);
		}
		return jabberID;
	}

	public synchronized Object connect(ID remote, Object data, int timeout) throws ECFException {
		if (connection != null)
			throw new ECFException("already connected");
		if (timeout > 0)
			SmackConfiguration.setPacketReplyTimeout(timeout);
		Roster.setDefaultSubscriptionMode(Roster.SUBSCRIPTION_MANUAL);

		final XMPPID jabberURI = getXMPPID(remote);
		final String username = jabberURI.getUsername();
		serverName = jabberURI.getHostname();
		serverPort = jabberURI.getPort();
		try {
			if (google) {
				if (secure) {
					if (serverPort == -1) {
						serverPort = XMPPS_DEFAULT_PORT;
					}
					connection = new SSLXMPPConnection(GOOGLE_TALK_HOST, serverPort, jabberURI.getHostname());
				} else {
					if (serverPort == -1) {
						serverPort = XMPP_DEFAULT_PORT;
					}
					connection = new XMPPConnection(GOOGLE_TALK_HOST, serverPort, jabberURI.getHostname());
				}
			} else if (serverPort == -1) {
				if (secure) {
					connection = new SSLXMPPConnection(serverName);
				} else {
					connection = new XMPPConnection(serverName);
				}
			} else {
				if (secure) {
					connection = new SSLXMPPConnection(serverName, serverPort);
				} else {
					connection = new XMPPConnection(serverName, serverPort);
				}
			}
			connection.addPacketListener(packetListener, null);
			connection.addConnectionListener(connectionListener);
			// Login
			connection.login(username, (String) data, CLIENT_TYPE);
			isConnected = true;
		} catch (final XMPPException e) {
			if (e.getMessage().equals("(401)"))
				throw new ContainerAuthenticationException("Password incorrect", e);
			throw new ContainerConnectException(e.getLocalizedMessage(), e);
		}
		return null;
	}

	public void sendPacket(Packet packet) throws XMPPException {
		if (connection != null)
			connection.sendPacket(packet);
	}

	public synchronized void disconnect() {
		disconnecting = true;
		if (isStarted()) {
			stop();
		}
		if (connection != null) {
			connection.removePacketListener(packetListener);
			connection.removeConnectionListener(connectionListener);
			connection.close();
			isConnected = false;
			connection = null;
		}
	}

	public synchronized boolean isConnected() {
		return (isConnected);
	}

	public synchronized ID getLocalID() {
		if (!isConnected())
			return null;
		try {
			return IDFactory.getDefault().createID(namespace.getName(), new Object[] {connection.getConnectionID()});
		} catch (final Exception e) {
			logException("Exception in getLocalID", e);
			return null;
		}
	}

	public synchronized void start() {
		if (isStarted())
			return;
		isStarted = true;
	}

	public boolean isStarted() {
		return isStarted;
	}

	public synchronized void stop() {
		isStarted = false;
	}

	protected void handleConnectionClosed(Exception e) {
		if (!disconnecting) {
			disconnecting = true;
			handler.handleDisconnectEvent(new DisconnectEvent(this, e, null));
		}
	}

	protected void handlePacket(Packet arg0) {
		try {
			final Object val = arg0.getProperty(OBJECT_PROPERTY_NAME);
			if (val != null) {
				handler.handleAsynchEvent(new ECFConnectionObjectPacketEvent(this, arg0, val));
			} else {
				handler.handleAsynchEvent(new ECFConnectionPacketEvent(this, arg0));
			}
		} catch (final IOException e) {
			logException("Exception in handleAsynchEvent", e);
			try {
				disconnect();
			} catch (final Exception e1) {
				logException("Exception in disconnect()", e1);
			}
		}
	}

	public synchronized void sendAsynch(ID receiver, byte[] data) throws IOException {
		if (data == null)
			throw new IOException("no data");
		final Message aMsg = new Message();
		aMsg.setProperty(OBJECT_PROPERTY_NAME, data);
		sendMessage(receiver, aMsg);
	}

	protected void sendMessage(ID receiver, Message aMsg) throws IOException {
		synchronized (this) {
			if (!isConnected())
				throw new IOException("not connected");
			try {
				if (receiver == null)
					throw new IOException("receiver cannot be null for xmpp instant messaging");
				else if (receiver instanceof XMPPID) {
					final XMPPID rcvr = (XMPPID) receiver;
					aMsg.setType(Message.Type.CHAT);
					final String userAtHost = rcvr.getUsernameAtHost();
					final Chat localChat = connection.createChat(userAtHost);
					localChat.sendMessage(aMsg);
				} else if (receiver instanceof XMPPRoomID) {
					final XMPPRoomID roomID = (XMPPRoomID) receiver;
					aMsg.setType(Message.Type.GROUP_CHAT);
					final String to = roomID.getMucString();
					aMsg.setTo(to);
					connection.sendPacket(aMsg);
				} else
					throw new IOException("receiver must be of type XMPPID or XMPPRoomID");
			} catch (final XMPPException e) {
				final IOException result = new IOException("XMPPException in sendMessage: " + e.getMessage());
				result.setStackTrace(e.getStackTrace());
				throw result;
			}
		}
	}

	public synchronized Object sendSynch(ID receiver, byte[] data) throws IOException {
		if (data == null)
			throw new IOException("data cannot be null");
		// This is assumed to be disconnect...so we'll just disconnect
		// disconnect();
		return null;
	}

	public void addListener(IConnectionListener listener) {
		// XXX Not yet implemented
	}

	public void removeListener(IConnectionListener listener) {
		// XXX Not yet implemented
	}

	public void sendMessage(ID target, String message) throws IOException {
		if (target == null)
			throw new IOException("target cannot be null");
		if (message == null)
			throw new IOException("message cannot be null");
		final Message aMsg = new Message();
		aMsg.setBody(message);
		sendMessage(target, aMsg);
	}

	public static Map getPropertiesFromPacket(Packet packet) {
		final Map result = new HashMap();
		final Iterator i = packet.getPropertyNames();
		for (; i.hasNext();) {
			final String name = (String) i.next();
			result.put(name, packet.getProperty(name));
		}
		return result;
	}

	public static Packet setPropertiesInPacket(Packet input, Map properties) {
		if (properties != null) {
			for (final Iterator i = properties.keySet().iterator(); i.hasNext();) {
				final Object keyo = i.next();
				final Object val = properties.get(keyo);
				final String key = (keyo instanceof String) ? (String) keyo : keyo.toString();
				if (val instanceof Boolean)
					input.setProperty(key, ((Boolean) val).booleanValue());
				else if (val instanceof Double)
					input.setProperty(key, ((Double) val).doubleValue());
				else if (val instanceof Float)
					input.setProperty(key, ((Float) val).floatValue());
				else if (val instanceof Integer)
					input.setProperty(key, ((Integer) val).intValue());
				else if (val instanceof Long)
					input.setProperty(key, ((Long) val).floatValue());
				else if (val instanceof Object)
					input.setProperty(key, val);
			}
		}
		return input;
	}

	public void sendMessage(ID target, ID thread, Type type, String subject, String body, Map properties2) throws IOException {
		if (target == null)
			throw new IOException("XMPP target for message cannot be null");
		if (body == null)
			body = "";
		final Message aMsg = new Message();
		aMsg.setBody(body);
		if (thread != null)
			aMsg.setThread(thread.getName());
		if (type != null)
			aMsg.setType(type);
		if (subject != null)
			aMsg.setSubject(subject);
		setPropertiesInPacket(aMsg, properties2);
		sendMessage(target, aMsg);
	}

	public void sendPresenceUpdate(ID target, Presence presence) throws IOException {
		if (presence == null)
			throw new IOException("presence cannot be null");
		presence.setFrom(connection.getUser());
		if (target != null)
			presence.setTo(target.getName());
		synchronized (this) {
			if (!isConnected())
				throw new IOException("not connected");
			connection.sendPacket(presence);
		}
	}

	public void sendRosterAdd(String user, String name, String[] groups) throws IOException, XMPPException {
		final Roster r = getRoster();
		r.createEntry(user, name, groups);
	}

	public void sendRosterRemove(String user) throws XMPPException, IOException {
		final Roster r = getRoster();
		final RosterEntry re = r.getEntry(user);
		r.removeEntry(re);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.provider.xmpp.IIMMessageSender#getRoster()
	 */
	public Roster getRoster() throws IOException {
		if (connection == null || !connection.isConnected())
			return null;
		return connection.getRoster();
	}

}
