/****************************************************************************
 * Copyright (c) 2006, 2007 Remy Suen, 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:
 *    Remy Suen <remy.suen@gmail.com> - initial API and implementation
 *****************************************************************************/
package org.eclipse.ecf.internal.provider.msn;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.ecf.core.ContainerConnectException;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.IContainerListener;
import org.eclipse.ecf.core.events.ContainerConnectedEvent;
import org.eclipse.ecf.core.events.ContainerConnectingEvent;
import org.eclipse.ecf.core.events.ContainerDisconnectedEvent;
import org.eclipse.ecf.core.events.ContainerDisconnectingEvent;
import org.eclipse.ecf.core.events.ContainerDisposeEvent;
import org.eclipse.ecf.core.events.IContainerEvent;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDCreateException;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.identity.Namespace;
import org.eclipse.ecf.core.security.IConnectContext;
import org.eclipse.ecf.core.security.ObjectCallback;
import org.eclipse.ecf.core.security.UnsupportedCallbackException;
import org.eclipse.ecf.core.user.IUser;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.presence.IAccountManager;
import org.eclipse.ecf.presence.IIMMessageListener;
import org.eclipse.ecf.presence.IPresence;
import org.eclipse.ecf.presence.IPresenceContainerAdapter;
import org.eclipse.ecf.presence.IPresenceListener;
import org.eclipse.ecf.presence.IPresenceSender;
import org.eclipse.ecf.presence.chatroom.IChatRoomManager;
import org.eclipse.ecf.presence.history.IHistory;
import org.eclipse.ecf.presence.history.IHistoryManager;
import org.eclipse.ecf.presence.im.ChatMessage;
import org.eclipse.ecf.presence.im.ChatMessageEvent;
import org.eclipse.ecf.presence.im.IChat;
import org.eclipse.ecf.presence.im.IChatManager;
import org.eclipse.ecf.presence.im.IChatMessageSender;
import org.eclipse.ecf.presence.im.ITypingMessageSender;
import org.eclipse.ecf.presence.im.TypingMessage;
import org.eclipse.ecf.presence.im.TypingMessageEvent;
import org.eclipse.ecf.presence.im.IChatMessage.Type;
import org.eclipse.ecf.presence.roster.IRoster;
import org.eclipse.ecf.presence.roster.IRosterEntry;
import org.eclipse.ecf.presence.roster.IRosterGroup;
import org.eclipse.ecf.presence.roster.IRosterItem;
import org.eclipse.ecf.presence.roster.IRosterListener;
import org.eclipse.ecf.presence.roster.IRosterManager;
import org.eclipse.ecf.presence.roster.IRosterSubscriptionListener;
import org.eclipse.ecf.presence.roster.IRosterSubscriptionSender;
import org.eclipse.ecf.presence.search.ICriteria;
import org.eclipse.ecf.presence.search.ISearch;
import org.eclipse.ecf.presence.search.IRestriction;
import org.eclipse.ecf.presence.search.IUserSearchListener;
import org.eclipse.ecf.presence.search.IUserSearchManager;
import org.eclipse.ecf.presence.search.UserSearchException;
import org.eclipse.ecf.presence.search.message.IMessageSearchManager;
import org.eclipse.ecf.presence.service.IPresenceService;
import org.eclipse.ecf.protocol.msn.ChatSession;
import org.eclipse.ecf.protocol.msn.Contact;
import org.eclipse.ecf.protocol.msn.Group;
import org.eclipse.ecf.protocol.msn.MsnClient;
import org.eclipse.ecf.protocol.msn.Status;
import org.eclipse.ecf.protocol.msn.events.IChatSessionListener;
import org.eclipse.ecf.protocol.msn.events.IContactListListener;
import org.eclipse.ecf.protocol.msn.events.IContactListener;
import org.eclipse.ecf.protocol.msn.events.ISessionListener;

final class MSNContainer implements IContainer, IChatManager,
		IChatMessageSender, IPresenceService, IPresenceSender, IRoster,
		IRosterManager, IRosterSubscriptionSender, ITypingMessageSender {

	private final Map chatSessions;

	private final List containerListeners;

	private final List updateListeners;

	private final List messageListeners;

	private final List presenceListeners;

	private final List subscriptionListeners;

	private final List entries;

	private final IUser user;

	private final Namespace namespace;

	private final ID guid;

	private MsnClient client;

	private MSNID connectID;

	protected IHistoryManager historyManager = new IHistoryManager() {

		public IHistory getHistory(ID partnerID, Map options) {
			// TODO Auto-generated method stub
			return null;
		}

		public boolean isActive() {
			// TODO Auto-generated method stub
			return false;
		}

		public void setActive(boolean active) {
			// TODO Auto-generated method stub

		}

		public Object getAdapter(Class adapter) {
			// TODO Auto-generated method stub
			return null;
		}

	};

	MSNContainer() throws IDCreateException {
		guid = IDFactory.getDefault().createGUID();
		namespace = IDFactory.getDefault().getNamespaceByName(
				Activator.NAMESPACE_ID);
		user = new Account();
		chatSessions = new Hashtable();
		containerListeners = new ArrayList();
		updateListeners = new ArrayList();
		messageListeners = new ArrayList();
		presenceListeners = new ArrayList();
		subscriptionListeners = new ArrayList();
		entries = new ArrayList();
	}

	public void connect(ID targetID, IConnectContext connectContext)
			throws ContainerConnectException {
		if (!(targetID instanceof MSNID)) {
			throw new ContainerConnectException(
					Messages.MSNContainer_TargetIDNotMSNID);
		}

		client = new MsnClient();
		ObjectCallback[] cb = { new ObjectCallback() };
		try {
			connectContext.getCallbackHandler().handle(cb);
			client.addSessionListener(new ISessionListener() {
				public void sessionConnected(ChatSession session) {
					try {
						Contact contact = session.getParticipants()[0];
						final ID toID = namespace
								.createInstance(new Object[] { contact
										.getEmail() });
						chatSessions.put(toID, session);
						session.addChatSessionListener(new ChatSessionListener(
								toID));
					} catch (IDCreateException e) {
						// ignored since this should not be possible
					}
				}
			});

			client.getContactList().addContactListListener(
					new IContactListListener() {
						public void contactAdded(Contact contact) {
							final MSNRosterEntry entry = new MSNRosterEntry(
									MSNContainer.this, contact, namespace);

							for (int i = 0; i < entries.size(); i++) {
								Object e = entries.get(i);
								if (e instanceof MSNRosterGroup) {
									MSNRosterGroup group = (MSNRosterGroup) e;
									if (group.getGroup().contains(contact)) {
										MSNRosterEntry check = group
												.getEntryFor(contact);
										if (check == null) {
											check = entry;
											contact
													.addContactListener(new IContactListener() {
														public void nameChanged(
																String name) {
															firePresence(
																	entry
																			.getID(),
																	entry
																			.getPresence());
															fireRosterUpdate(entry);
														}

														public void personalMessageChanged(
																String personalMessage) {
															entry
																	.updatePersonalMessage();
															firePresence(
																	entry
																			.getID(),
																	entry
																			.getPresence());
															fireRosterUpdate(entry);
														}

														public void statusChanged(
																Status status) {
															firePresence(
																	entry
																			.getID(),
																	entry
																			.getPresence());
															fireRosterUpdate(entry);
														}
													});
											group.add(check);
											fireRosterEntryAdded(check);
										}
										fireRosterUpdate(group);
										return;
									}
								} else {
									MSNRosterEntry check = (MSNRosterEntry) e;
									if (entry.getContact().equals(
											check.getContact())) {
										fireRosterEntryAdded(check);
										fireRosterUpdate(check.getParent());
										return;
									}
								}
							}

							contact.addContactListener(new IContactListener() {
								public void nameChanged(String name) {
									firePresence(entry.getID(), entry
											.getPresence());
									fireRosterUpdate(entry);
								}

								public void personalMessageChanged(
										String personalMessage) {
									entry.updatePersonalMessage();
									firePresence(entry.getID(), entry
											.getPresence());
									fireRosterUpdate(entry);
								}

								public void statusChanged(Status status) {
									firePresence(entry.getID(), entry
											.getPresence());
									fireRosterUpdate(entry);
								}
							});
							entries.add(entry);
							entry.setParent(MSNContainer.this);
							fireRosterEntryAdded(entry);
							fireRosterUpdate(MSNContainer.this);
						}

						public void contactRemoved(Contact contact) {
							MSNRosterEntry entry = findEntry(entries, contact
									.getEmail());
							if (entry != null) {
								fireHandleUnsubscribed(entry.getUser().getID());
								fireRosterEntryRemoved(entry);
								fireRosterUpdate(entry.getParent());
								if (entry.getContact().getGroups().isEmpty()) {
									entry.setParent(MSNContainer.this);
									fireRosterUpdate(MSNContainer.this);
								}
							}
						}

						public void contactAddedUser(String email) {
							try {
								fireHandleSubscriptionRequest(namespace
										.createInstance(new Object[] { email }));
							} catch (IDCreateException e) {
								// ignored
							}
						}

						public void contactRemovedUser(String email) {
							// nothing to do
						}

						public void groupAdded(Group group) {
							entries.add(new MSNRosterGroup(MSNContainer.this,
									group));
						}
					});

			fireContainerEvent(new ContainerConnectingEvent(guid, targetID));
			client.connect(targetID.getName(), (String) cb[0].getObject());
			connectID = (MSNID) targetID;
			fireContainerEvent(new ContainerConnectedEvent(guid, connectID));
			Activator.getDefault().registerService(this);
		} catch (UnsupportedCallbackException e) {
			throw new ContainerConnectException(e);
		} catch (IOException e) {
			throw new ContainerConnectException(e);
		}
	}

	private MSNRosterEntry findEntry(Collection entries, String email) {
		for (Iterator it = entries.iterator(); it.hasNext();) {
			Object o = it.next();
			if (o instanceof IRosterGroup) {
				MSNRosterEntry entry = findEntry(((IRosterGroup) o)
						.getEntries(), email);
				if (entry != null) {
					return entry;
				}
			} else {
				MSNRosterEntry entry = (MSNRosterEntry) o;
				if (entry.getUser().getID().getName().equals(email)) {
					return entry;
				}
			}
		}
		return null;
	}

	public void disconnect() {
		if (client != null) {
			fireContainerEvent(new ContainerDisconnectingEvent(guid, connectID));
			client.disconnect();
			fireContainerEvent(new ContainerDisconnectedEvent(guid, connectID));
			for (Iterator it = chatSessions.values().iterator(); it.hasNext();) {
				((ChatSession) it.next()).close();
			}
			chatSessions.clear();
			connectID = null;
			client = null;
			Activator.getDefault().unregisterService(this);
		}
	}

	public void dispose() {
		disconnect();
		fireContainerEvent(new ContainerDisposeEvent(guid));
	}

	private void fireContainerEvent(IContainerEvent event) {
		synchronized (containerListeners) {
			for (int i = 0; i < containerListeners.size(); i++) {
				((IContainerListener) containerListeners.get(i))
						.handleEvent(event);
			}
		}
	}

	private void fireMessageEvent(ID fromID, String message) {
		synchronized (messageListeners) {
			for (int i = 0; i < messageListeners.size(); i++) {
				((IIMMessageListener) messageListeners.get(i))
						.handleMessageEvent(new ChatMessageEvent(fromID,
								new ChatMessage(fromID, message)));
			}
		}
	}

	private void fireTypingMessageEvent(ID fromID) {
		synchronized (messageListeners) {
			for (int i = 0; i < messageListeners.size(); i++) {
				((IIMMessageListener) messageListeners.get(i))
						.handleMessageEvent(new TypingMessageEvent(fromID,
								new TypingMessage(fromID, true, null)));
			}
		}
	}

	private void fireRosterUpdate(IRosterItem item) {
		synchronized (updateListeners) {
			for (int i = 0; i < updateListeners.size(); i++) {
				((IRosterListener) updateListeners.get(i)).handleRosterUpdate(
						this, item);
			}
		}
	}

	private void fireRosterEntryAdded(IRosterEntry entry) {
		synchronized (updateListeners) {
			for (int i = 0; i < updateListeners.size(); i++) {
				((IRosterListener) updateListeners.get(i))
						.handleRosterEntryAdd(entry);
			}
		}
	}

	private void fireRosterEntryRemoved(IRosterEntry entry) {
		synchronized (updateListeners) {
			for (int i = 0; i < updateListeners.size(); i++) {
				((IRosterListener) updateListeners.get(i))
						.handleRosterEntryRemove(entry);
			}
		}
	}

	private void firePresence(ID id, IPresence presence) {
		synchronized (presenceListeners) {
			for (int i = 0; i < presenceListeners.size(); i++) {
				((IPresenceListener) presenceListeners.get(i)).handlePresence(
						id, presence);
			}
		}
	}

	private void fireHandleSubscriptionRequest(ID fromID) {
		synchronized (subscriptionListeners) {
			for (int i = 0; i < subscriptionListeners.size(); i++) {
				((IRosterSubscriptionListener) subscriptionListeners.get(i))
						.handleSubscribeRequest(fromID);
			}
		}
	}

	private void fireHandleUnsubscribed(ID fromID) {
		synchronized (subscriptionListeners) {
			for (int i = 0; i < subscriptionListeners.size(); i++) {
				((IRosterSubscriptionListener) subscriptionListeners.get(i))
						.handleUnsubscribed(fromID);
			}
		}
	}

	public Object getAdapter(Class serviceType) {
		if (serviceType != null && serviceType.isInstance(this)) {
			return this;
		} else {
			return null;
		}
	}

	public Namespace getConnectNamespace() {
		return IDFactory.getDefault()
				.getNamespaceByName(Activator.NAMESPACE_ID);
	}

	public ID getConnectedID() {
		return connectID;
	}

	public ID getID() {
		return guid;
	}

	public IAccountManager getAccountManager() {
		return null;
	}

	public IChatRoomManager getChatRoomManager() {
		return null;
	}

	public IPresenceSender getPresenceSender() {
		return this;
	}

	public void addListener(IContainerListener listener) {
		if (listener != null) {
			synchronized (containerListeners) {
				if (!containerListeners.contains(listener)) {
					containerListeners.add(listener);
				}
			}
		}
	}

	public void removeListener(IContainerListener listener) {
		if (listener != null) {
			synchronized (containerListeners) {
				containerListeners.remove(listener);
			}
		}
	}

	private class ChatSessionListener implements IChatSessionListener {

		private ID toID;

		private ChatSessionListener(ID toID) {
			this.toID = toID;
		}

		public void contactIsTyping(Contact contact) {
			fireTypingMessageEvent(toID);
		}

		public void contactJoined(Contact contact) {
		}

		public void contactLeft(Contact contact) {
			chatSessions.remove(toID);
		}

		public void messageReceived(Contact contact, String message) {
			fireMessageEvent(toID, message);
		}

		public void sessionTimedOut() {
			chatSessions.remove(toID);
		}

	}

	public void sendPresenceUpdate(ID toID, IPresence presence)
			throws ECFException {
		if (presence == null || client == null) {
			throw new ECFException();
		}

		IPresence.Mode mode = presence.getMode();
		try {
			client.setPersonalMessage(presence.getStatus());
			if (presence.getType() == IPresence.Type.UNAVAILABLE) {
				disconnect();
			} else if (mode == IPresence.Mode.AVAILABLE
					|| mode == IPresence.Mode.CHAT) {
				client.setStatus(Status.ONLINE);
			} else if (mode == IPresence.Mode.AWAY
					|| mode == IPresence.Mode.EXTENDED_AWAY) {
				client.setStatus(Status.AWAY);
			} else if (mode == IPresence.Mode.DND) {
				client.setStatus(Status.BUSY);
			} else {
				client.setStatus(Status.APPEAR_OFFLINE);
			}
		} catch (IOException e) {
			throw new ECFException(e);
		}
	}

	public IRosterManager getRosterManager() {
		return this;
	}

	public void addRosterListener(IRosterListener listener) {
		synchronized (updateListeners) {
			if (!updateListeners.contains(listener)) {
				updateListeners.add(listener);
			}
		}
	}

	public IRoster getRoster() {
		return this;
	}

	public IRosterSubscriptionSender getRosterSubscriptionSender() {
		return this;
	}

	public void addRosterSubscriptionListener(
			IRosterSubscriptionListener listener) {
		if (listener != null) {
			synchronized (subscriptionListeners) {
				if (!subscriptionListeners.contains(listener)) {
					subscriptionListeners.add(listener);
				}
			}
		}
	}

	public void removeRosterSubscriptionListener(
			IRosterSubscriptionListener listener) {
		if (listener != null) {
			synchronized (subscriptionListeners) {
				subscriptionListeners.remove(listener);
			}
		}
	}

	public void removeRosterListener(IRosterListener listener) {
		if (listener != null) {
			synchronized (updateListeners) {
				updateListeners.remove(listener);
			}
		}
	}

	public Collection getItems() {
		return Collections.unmodifiableCollection(entries);
	}

	public IUser getUser() {
		return connectID == null ? null : user;
	}

	public void addPresenceListener(IPresenceListener listener) {
		if (listener != null) {
			synchronized (presenceListeners) {
				if (!presenceListeners.contains(listener)) {
					presenceListeners.add(listener);
				}
			}
		}
	}

	public void removePresenceListener(IPresenceListener listener) {
		if (listener != null) {
			synchronized (presenceListeners) {
				presenceListeners.remove(listener);
			}
		}
	}

	public IChatManager getChatManager() {
		return this;
	}

	public IChatMessageSender getChatMessageSender() {
		return this;
	}

	public ITypingMessageSender getTypingMessageSender() {
		return this;
	}

	public void sendChatMessage(ID toID, ID threadID, Type type,
			String subject, String body, Map properties) throws ECFException {
		sendChatMessage(toID, body);
	}

	public void sendChatMessage(ID toID, String body) throws ECFException {
		try {
			ChatSession cs = (ChatSession) chatSessions.get(toID);
			if (cs == null) {
				cs = client.createChatSession(toID.getName());
				cs.addChatSessionListener(new ChatSessionListener(toID));
				chatSessions.put(toID, cs);
			}
			cs.sendMessage(body);
		} catch (IOException e) {
			throw new ECFException(e);
		}
	}

	public void sendTypingMessage(ID toID, boolean isTyping, String body)
			throws ECFException {
		try {
			if (isTyping) {
				ChatSession cs = (ChatSession) chatSessions.get(toID);
				if (cs == null) {
					cs = client.createChatSession(toID.getName());
					cs.addChatSessionListener(new ChatSessionListener(toID));
					chatSessions.put(toID, cs);
				}
				cs.sendTypingNotification();
			}
		} catch (IOException e) {
			throw new ECFException(e);
		}
	}

	public void addMessageListener(IIMMessageListener listener) {
		if (listener != null) {
			synchronized (messageListeners) {
				if (!messageListeners.contains(listener)) {
					messageListeners.add(listener);
				}
			}
		}
	}

	public void removeMessageListener(IIMMessageListener listener) {
		if (listener != null) {
			synchronized (messageListeners) {
				messageListeners.remove(listener);
			}
		}
	}

	private class Account implements IUser {

		private static final long serialVersionUID = 7497082891662391996L;

		public Object getAdapter(Class adapter) {
			return null;
		}

		public ID getID() {
			return connectID;
		}

		public Map getProperties() {
			return null;
		}

		public String getName() {
			return client.getUserEmail();
		}

		public String getNickname() {
			return client.getDisplayName();
		}

	}

	public void sendRosterAdd(String user, String name, String[] groups)
			throws ECFException {
		try {
			client.getContactList().addContact(user, name);
		} catch (IOException e) {
			throw new ECFException(e);
		}
	}

	public void sendRosterRemove(ID userID) throws ECFException {
		MSNRosterEntry entry = findEntry(entries, userID.getName());
		if (entry != null) {
			try {
				client.getContactList().removeContact(entry.getContact());
			} catch (IOException e) {
				throw new ECFException(e);
			}
		}
	}

	public String getName() {
		IUser user = getUser();
		return user == null ? null : user.getName();
	}

	public IRosterItem getParent() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.presence.im.IChatManager#getHistoryManager()
	 */
	public IHistoryManager getHistoryManager() {
		// TODO Auto-generated method stub
		return historyManager;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.presence.roster.IRoster#getPresenceContainerAdapter()
	 */
	public IPresenceContainerAdapter getPresenceContainerAdapter() {
		return this;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.presence.im.IChatManager#createChat(org.eclipse.ecf.core.identity.ID)
	 */
	public IChat createChat(ID targetUser, IIMMessageListener messageListener) throws ECFException {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * TODO Implement a User Search Manager for MSN
	 * for while it just returns a manger
	 * to inform that user search is not allow
	 * for this provider see {@link IUserSearchManager#isEnabled()}
	 */
	public IUserSearchManager getUserSearchManager() {
		return new IUserSearchManager(){

			public ICriteria createCriteria() {
				// TODO Auto-generated method stub
				return null;
			}

			public IRestriction createRestriction() {
				// TODO Auto-generated method stub
				return null;
			}

			public String[] getUserPropertiesFields()
					throws ContainerConnectException {
				// TODO Auto-generated method stub
				return null;
			}

			public boolean isEnabled() {
				// TODO Auto-generated method stub
				return false;
			}

			public ISearch search(ICriteria criteria)
					throws UserSearchException {
				// TODO Auto-generated method stub
				return null;
			}

			public void search(ICriteria criteria, IUserSearchListener listener) {
				// TODO Auto-generated method stub
				
			}
			
		};
	}

	public IMessageSearchManager getMessageSearchManager() {
		// TODO Auto-generated method stub
		return null;
	}

}
