/*******************************************************************************
 * Copyright (c) 2004 Peter Nehrer and Composent, Inc.
 * 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:
 *     Peter Nehrer - initial API and implementation
 *******************************************************************************/
package org.eclipse.ecf.example.sdo.editor;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.ecf.core.events.IContainerConnectedEvent;
import org.eclipse.ecf.core.events.IContainerDisconnectedEvent;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.sharedobject.ISharedObject;
import org.eclipse.ecf.core.sharedobject.ISharedObjectConfig;
import org.eclipse.ecf.core.sharedobject.ISharedObjectContext;
import org.eclipse.ecf.core.sharedobject.ReplicaSharedObjectDescription;
import org.eclipse.ecf.core.sharedobject.SharedObjectInitException;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectActivatedEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectCreateResponseEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectDeactivatedEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectMessageEvent;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.core.util.Event;

/**
 * <p>
 * Tracks explicit data graph publication (or any shared object presence,
 * really) across all containers in a connected group using the server replica
 * to bootstrap new members.
 * </p>
 * <p>
 * It works something like this:
 * </p>
 * <ul>
 * <li>The container should first check if an instance of this shared object
 * already exists in their container. If not, create one and add it.</li>
 * <li>The container should call {@link #add(ID) add()}once published/subscribed
 * to a data graph. The method will block until this object activates (if it
 * hasn't already).</li>
 * <li>Upon activation, the primary instance replicates everywhere. This is to
 * assure that there is a server replica (and a replica in the initial set of
 * connected containers).</li>
 * <li>When a new container joins the group, the server will create a replica
 * in it, initialized with its current graph location table. This is to assure
 * that new members are properly bootstrapped.</li>
 * <li>All replicas broadcast additions/removals of their local data graphs and
 * listen to remote additions/removals in order to keep track of what is
 * published and where.</li>
 * <li>When a container leaves the group, all replicas note it and update their
 * graph location tables. Likewise, when a replica deactivates, it broadcasts
 * its departure so others may update their tables.</li>
 * </ul>
 * <p>
 * It is assumed that the container implementation used with this class is
 * server-centric. That is, there is a server that is always connected before
 * any other container may connect. When the server disconnects, everyone else
 * in effect disconnects.
 * </p>
 * 
 * @author pnehrer
 */
public class PublishedGraphTracker implements ISharedObject {

	private static final ID[] NO_GRAPHS = {};

	private static final int ADD = 0;

	private static final int REMOVE = 1;

	private static final int LEAVE = 2;

	private static final String ARG_TABLE = "table";

	private class Table {

		private final Hashtable graphs = new Hashtable();

		private final Hashtable containers = new Hashtable();

		public synchronized void add(ID containerID, ID graphID) {
			HashSet list = (HashSet) graphs.get(containerID);
			if (list == null) {
				list = new HashSet();
				graphs.put(containerID, list);
			}

			list.add(graphID);
			list = (HashSet) containers.get(containerID);
			if (list == null) {
				list = new HashSet();
				containers.put(graphID, list);
			}

			list.add(containerID);
		}

		public synchronized void remove(ID containerID, ID graphID) {
			HashSet list = (HashSet) graphs.get(containerID);
			if (list != null) {
				list.remove(graphID);
				if (list.isEmpty())
					graphs.remove(containerID);
			}

			list = (HashSet) containers.get(graphID);
			if (list != null) {
				list.remove(containerID);
				if (list.isEmpty())
					containers.remove(graphID);
			}
		}

		public synchronized void remove(ID containerID) {
			HashSet list = (HashSet) graphs.get(containerID);
			if (list != null) {
				for (Iterator i = list.iterator(); i.hasNext();) {
					ID graphID = (ID) i.next();
					list = (HashSet) containers.get(graphID);
					if (list != null) {
						list.remove(containerID);
						if (list.isEmpty())
							containers.remove(graphID);
					}
				}
			}
		}

		public synchronized boolean contains(ID graphID) {
			return containers.containsKey(graphID);
		}

		public synchronized ID[] getGraphs(ID containerID) {
			HashSet list = (HashSet) graphs.get(containerID);
			return list == null ? NO_GRAPHS : (ID[]) list.toArray(new ID[list
					.size()]);
		}

		public synchronized Object createMemento() {
			return new Hashtable[] { graphs, containers };
		}

		public synchronized void load(Object memento) {
			Hashtable[] tables = (Hashtable[]) memento;
			graphs.putAll(tables[0]);
			containers.putAll(tables[1]);
		}
	}

	private final Table table = new Table();

	private ISharedObjectConfig config;

	private ISharedObjectContext context;

	private final Object activationMutex = new Object();

	private boolean activated;

	/**
	 * Adds a graph to the list of published graphs.
	 * 
	 * @param graphID
	 *            identifier of the graph that was published
	 * @throws ECFException
	 */
	public synchronized void add(ID graphID) throws ECFException {
		if (config == null)
			throw new ECFException("Not initialized.");

		// wait to be activated before proceeding
		synchronized (activationMutex) {
			if (!activated)
				try {
					activationMutex.wait(1000);
				} catch (InterruptedException e) {
					throw new ECFException(e);
				}

			if (!activated)
				throw new ECFException("Not activated.");
		}

		// tell everyone a graph was published
		try {
			getContext().sendMessage(null,
					new Object[] { new Integer(ADD), graphID });
		} catch (IOException e) {
			throw new ECFException(e);
		}

		// track it yourself
		handleAdd(getContext().getLocalContainerID(), graphID);
	}

	/**
	 * Answers whether a graph is published (at the time of invocation).
	 * 
	 * @param graphID
	 *            identifier of the graph whose publishing status to return
	 * @return <code>true</code> if the graph is published
	 */
	public synchronized boolean isPublished(ID graphID) {
		return table.contains(graphID);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig)
	 */
	public synchronized void init(ISharedObjectConfig initData)
			throws SharedObjectInitException {
		if (config == null)
			config = initData;
		else
			throw new SharedObjectInitException("Already initialized.");

		Map props = (Map) config.getProperties();
		if (props != null) {
			Object memento = props.get(ARG_TABLE);
			if (memento != null)
				table.load(memento);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event)
	 */
	public void handleEvent(Event event) {
		if (event instanceof ISharedObjectCreateResponseEvent) {
			// Ignore
		} else if (event instanceof ISharedObjectMessageEvent) {
			// track graph additions/removals and peer departures
			// (deactivations)
			ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
			Object[] data = (Object[]) e.getData();
			Integer type = (Integer) data[0];
			switch (type.intValue()) {
			case ADD:
				handleAdd(e.getRemoteContainerID(), (ID) data[1]);
				break;

			case REMOVE:
				handleRemove(e.getRemoteContainerID(), (ID) data[1]);
				break;

			case LEAVE:
				handleLeave(e.getRemoteContainerID());
				break;
			}
		} else if (event instanceof IContainerConnectedEvent) {
			IContainerConnectedEvent e = (IContainerConnectedEvent) event;
			if (e.getTargetID().equals(
					getContext().getLocalContainerID()))
				// this container joined
				handleJoined();
			else if (getContext().isGroupManager())
				// some other container joined and we're the server
				handleJoined(e.getTargetID());
		} else if (event instanceof IContainerDisconnectedEvent) {
			IContainerDisconnectedEvent e = (IContainerDisconnectedEvent) event;
			// some other container departed -- same as peer deactivation
			if (!e.getTargetID().equals(
					getContext().getLocalContainerID()))
				handleLeave(e.getTargetID());
		} else if (event instanceof ISharedObjectActivatedEvent) {
			ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
			if (e.getActivatedID().equals(config.getSharedObjectID()))
				// we're being activated
				handleActivated();
		} else if (event instanceof ISharedObjectDeactivatedEvent) {
			ISharedObjectDeactivatedEvent e = (ISharedObjectDeactivatedEvent) event;
			if (e.getDeactivatedID().equals(config.getSharedObjectID()))
				// we're being deactivated
				handleDeactivated();
			else if (table.contains(e.getDeactivatedID()))
				// a local graph we track is being deactivated
				handleRemoved(e.getDeactivatedID());
		}
	}

	private void handleAdd(ID containerID, ID graphID) {
		table.add(containerID, graphID);
	}

	private void handleRemove(ID containerID, ID graphID) {
		table.remove(containerID, graphID);
	}

	private void handleLeave(ID containerID) {
		table.remove(containerID);
	}

	private void handleJoined() {
		if (config.getHomeContainerID().equals(
				getContext().getLocalContainerID())) {
			// we're the primary copy -- replicate everywhere
			try {
				getContext().sendCreate(
						null,
						new ReplicaSharedObjectDescription(getClass(),config.getSharedObjectID(),
								config.getHomeContainerID()));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private void handleJoined(ID containerID) {
		Map props = new HashMap(1);
		props.put(ARG_TABLE, table.createMemento());
		try {
			getContext().sendCreate(
					containerID,
					new ReplicaSharedObjectDescription(getClass(),config.getSharedObjectID(),
							config.getHomeContainerID(), props));
		} catch (IOException ex) {
			// TODO Auto-generated catch block
			ex.printStackTrace();
		}
	}

	private void handleActivated() {
		handleJoined();
		synchronized (activationMutex) {
			activated = true;
			activationMutex.notifyAll();
		}
	}

	private void handleDeactivated() {
		try {
			getContext().sendMessage(null, new Object[] { new Integer(LEAVE) });
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		synchronized (activationMutex) {
			activated = false;
			activationMutex.notifyAll();
		}
	}

	private void handleRemoved(ID graphID) {
		try {
			getContext().sendMessage(null,
					new Object[] { new Integer(REMOVE), graphID });
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		handleRemove(getContext().getLocalContainerID(), graphID);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.core.ISharedObject#handleEvents(org.eclipse.ecf.core.util.Event[])
	 */
	public void handleEvents(Event[] events) {
		for (int i = 0; i < events.length; ++i)
			handleEvent(events[i]);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ecf.core.ISharedObject#dispose(org.eclipse.ecf.core.identity.ID)
	 */
	public synchronized void dispose(ID containerID) {
		config = null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class adapter) {
		return null;
	}

	private ISharedObjectContext getContext() {
		if (context == null)
			context = config.getContext();

		return context;
	}
}
