/*******************************************************************************
 * Copyright (c) 2001, 2005 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jem.internal.proxy.remote;
/*
 *  $RCSfile: REMRegistryController.java,v $
 *  $Revision: 1.12 $  $Date: 2005/08/24 20:39:06 $ 
 */

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;

import org.eclipse.jem.internal.proxy.core.ProxyPlugin;

/**
 * This class is a controller for all of the registries.
 * @author richkulp
 */
public class REMRegistryController {
	
	private Map fActiveRegistries = new HashMap();	// Access to this must be sync(REMRegistryController)
	private static final long CLEANUP_INTERVAL = 60000l;	// The interval between clean up job execution.
	
	protected boolean inShutdown;	// Are we in shutdown mode. Terminate registries runs differently in shutdown mode.
	
	// Thread to clean up GC'd proxies. Runs as a daemon at the lowest priority
	private Job processQueueJob= new Job(ProxyRemoteMessages.CleanupJob_title) { 
		public IStatus run(IProgressMonitor m) {
				REMProxyFactoryRegistry[] registries = null;
				synchronized (REMRegistryController.this) {
					// This list may be updated by others, so we need to make a copy
					// or else we could get a failure.
					registries = 
						(REMProxyFactoryRegistry[]) fActiveRegistries.values().toArray(
							new REMProxyFactoryRegistry[fActiveRegistries.size()]);
				}
				for (int i = 0; i < registries.length; i++) {
					try {
						((REMStandardBeanProxyFactory) registries[i].getBeanProxyFactory()).processQueue();					
					} catch (RuntimeException e) {
						// When debugging, getBeanProxyFactory can throw exception because it hasn't been initialized
						// yet when the thread wakes up, though the registry has been registered. It has to do with it 
						// can take significant time for the user to start up the debugger, and during that time this
						// thread could kick in.
					}
				}
			synchronized(this) {
				if (!m.isCanceled())
					this.schedule(CLEANUP_INTERVAL);	// Schedule to start again in one minute.
			}
			return Status.OK_STATUS;
		}

	}; //$NON-NLS-1$	
	
	public REMRegistryController() {

		ProxyPlugin.getPlugin().addProxyShutdownListener(new ProxyPlugin.IProxyPluginShutdownListener() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jem.internal.proxy.core.ProxyPlugin.IProxyPluginShutdownListener#shutdown()
			 */
			public void shutdown() {
				REMRegistryController.this.shutdown();
			}
		});

		masterThread = new REMMasterServerThread(this);
		masterThread.start();

		processQueueJob.setSystem(true);	// So that it won't show processing in process view. Not of interest to general users.
		processQueueJob.setPriority(Job.SHORT);
		processQueueJob.schedule(CLEANUP_INTERVAL);

	}
	
	/**
	 * Answer whether we are shutting down or not.
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public boolean inShutDown() {
		return inShutdown;
	}
	
	/*
	 * Add registry to list of active. Return a unique number to be the key.
	 * Package-protected so that only locals can access it.
	 */
	synchronized Integer registerRegistry(REMProxyFactoryRegistry registry) {
			
		Integer hashcode = new Integer(registry.hashCode());		
		while (true) {
			REMProxyFactoryRegistry existing = (REMProxyFactoryRegistry) fActiveRegistries.get(hashcode);
			if (existing == null)
				break;	// Not yet registered, use use the hashcode
			else if (existing != registry)
				hashcode = new Integer(hashcode.intValue()+1);						
			else
				return hashcode;	// Same guy, use the hashcode.
		}
		
		fActiveRegistries.put(hashcode, registry);
		return hashcode;
	}
	
	/*
	 * deregister the registry.
	 */
	synchronized void deregisterRegistry(Integer key) {
		fActiveRegistries.remove(key);
	}
	
	/*
	 * Return the registry for the given key
	 */
	synchronized REMProxyFactoryRegistry getRegistry(Integer key) {
		return (REMProxyFactoryRegistry) fActiveRegistries.get(key);
	}
	
	/**
	 * Master server thread. Handles keep-alive requests and register remote server threads.
	 * It will be created when needed.
	 */
	protected REMMasterServerThread masterThread;

	/*
	 * Shuts down this plug-in and discards all plug-in state.
	 *
	 * In this case, terminate all of the active registries so that they can be shutdown.
	 * Don't want them hanging around after termination of the desktop.
	 */
	void shutdown() {
		
		synchronized(processQueueJob) {
			processQueueJob.cancel();
		}
			
		REMProxyFactoryRegistry[] registries = null;
		synchronized (this) {
			// This list will be updated in the terminateRegistry, so we need to make a copy
			// or else we get a failure.
			registries = 
				(REMProxyFactoryRegistry[]) fActiveRegistries.values().toArray(
					new REMProxyFactoryRegistry[fActiveRegistries.size()]);
		}
		
		inShutdown = true;	// We are now in shutdown mode.
		// In shutdown mode the registries will not create the job that waits for the process
		// to terminate, and if it doesn't in 1.5 secs it does a force.
		// Instead what we will do is shutdown all of the registries. If they don't
		// shutdown on their own then they stay out there. But they do have an
		// internal timer that checks every five minutes to see if the host is 
		// still there, and if it isn't they will shut themselves down. They
		// would have to be really hosed if the suicide timer wasn't working.
		
		for (int i = 0; i < registries.length; i++)
			registries[i].terminateRegistry();
			
		if (masterThread != null) {
			try {
				masterThread.requestShutdown();
				masterThread.join(20000);	// Wait 20 seconds for everything to go down.
				masterThread = null;				
			} catch (InterruptedException e) {
			}
		}
		
		try {
			processQueueJob.join();
		} catch(InterruptedException e) {
		}
		
		REMProxyFactoryRegistry.cancelAllTerminateJobs();
	}
	
	/**
	 * Return the master socket port number.
	 */
	public int getMasterSocketPort() {
		return masterThread != null ? masterThread.getMasterSocket().getLocalPort() : -1;
	}	

}
