/****************************************************************************
 * Copyright (c) 2009 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.examples.remoteservices.hello.consumer;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.ecf.core.IContainerFactory;
import org.eclipse.ecf.examples.remoteservices.hello.HelloMessage;
import org.eclipse.ecf.examples.remoteservices.hello.IHello;
import org.eclipse.ecf.examples.remoteservices.hello.IHelloAsync;
import org.eclipse.ecf.osgi.services.distribution.IDistributionConstants;
import org.eclipse.ecf.remoteservice.IAsyncCallback;
import org.eclipse.ecf.remoteservice.IRemoteService;
import org.eclipse.ecf.remoteservice.IRemoteServiceProxy;
import org.eclipse.ecf.remoteservice.RemoteServiceHelper;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.equinox.concurrent.future.IFuture;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

public class HelloConsumerApplication implements IApplication,
		IDistributionConstants, ServiceTrackerCustomizer {

	public static final String CONSUMER_NAME = "org.eclipse.ecf.examples.remoteservices.hello.consumer";

	private BundleContext bundleContext;
	private ServiceTracker containerFactoryServiceTracker;

	private String containerType = "ecf.r_osgi.peer";

	private final Object appLock = new Object();
	private boolean done = false;

	private ServiceTracker helloServiceTracker;
	private ServiceRegistration discoveryListenerRegistration;
	private ServiceRegistration distributionListenerRegistration;

	public Object start(IApplicationContext appContext) throws Exception {
		// Set bundle context (for use with service trackers)
		bundleContext = Activator.getContext();
		processArgs(appContext);

		// Create ECF container of appropriate type. The container instance
		// can be created in a variety of ways...e.g. via code like the line below, 
		// via the new org.eclipse.ecf.container extension point, or automatically 
		// upon discovery via the IProxyContainerFinder/DefaultProxyContainerFinder.  
		getContainerFactory().createContainer(containerType);

		// Create service tracker to track IHello instances that have the 'service.imported'
		// property set (as defined by OSGi 4.2 remote services spec).
		helloServiceTracker = new ServiceTracker(bundleContext,
				createRemoteFilter(), this);
		helloServiceTracker.open();

		waitForDone();

		return IApplication.EXIT_OK;
	}

	private Filter createRemoteFilter() throws InvalidSyntaxException {
		// This filter looks for IHello instances that have the 
		// 'service.imported' property set, as specified by OSGi 4.2
		// remote services spec (Chapter 13)
		return bundleContext.createFilter("(&("
				+ org.osgi.framework.Constants.OBJECTCLASS + "="
				+ IHello.class.getName() + ")(" + SERVICE_IMPORTED + "=*))");
	}

	public void stop() {
		if (helloServiceTracker != null) {
			helloServiceTracker.close();
			helloServiceTracker = null;
		}
		if (containerFactoryServiceTracker != null) {
			containerFactoryServiceTracker.close();
			containerFactoryServiceTracker = null;
		}
		if (discoveryListenerRegistration != null) {
			discoveryListenerRegistration.unregister();
			discoveryListenerRegistration = null;
		}
		if (distributionListenerRegistration != null) {
			distributionListenerRegistration.unregister();
			distributionListenerRegistration = null;
		}
		this.bundleContext = null;
		synchronized (appLock) {
			done = true;
			appLock.notifyAll();
		}
	}

	private IContainerFactory getContainerFactory() {
		if (containerFactoryServiceTracker == null) {
			containerFactoryServiceTracker = new ServiceTracker(bundleContext,
					IContainerFactory.class.getName(), null);
			containerFactoryServiceTracker.open();
		}
		return (IContainerFactory) containerFactoryServiceTracker.getService();
	}

	private void processArgs(IApplicationContext appContext) {
		String[] originalArgs = (String[]) appContext.getArguments().get(
				"application.args");
		if (originalArgs == null)
			return;
		for (int i = 0; i < originalArgs.length; i++) {
			if (originalArgs[i].equals("-containerType")) {
				containerType = originalArgs[i + 1];
				i++;
			}
		}
	}

	private void waitForDone() {
		// then just wait here
		synchronized (appLock) {
			while (!done) {
				try {
					appLock.wait();
				} catch (InterruptedException e) {
					// do nothing
				}
			}
		}
	}

	/**
	 * Method called when a REMOTE IHello instance is registered.
	 */
	public Object addingService(ServiceReference reference) {
		System.out.println("IHello service proxy being added");
		// Since this reference is for a remote service,
		// The service object returned is a proxy implementing the
		// IHello interface
		IHello proxy = (IHello) bundleContext.getService(reference);
		// Call proxy synchronously.  Note that this call may block or fail due to 
		// synchronous communication with remote service
		System.out.println("STARTING remote call via proxy...");
		proxy.hello(CONSUMER_NAME+" via proxy");
		System.out.println("COMPLETED remote call via proxy");
		System.out.println();
		// Call other helloMessage method
		System.out.println("STARTING remote call via proxy...");
		proxy.helloMessage(new HelloMessage(CONSUMER_NAME+" via proxy","howdy"));
		System.out.println("COMPLETED remote call via proxy");
		System.out.println();

		// If the proxy is also an instance of IHelloAsync then use
		// this asynchronous interface to invoke methods asynchronously
		if (proxy instanceof IHelloAsync) {
			IHelloAsync helloA = (IHelloAsync) proxy;
			// Create callback for use in IHelloAsync
			IAsyncCallback callback = new IAsyncCallback<String>() {
				public void onSuccess(String result) {
					System.out.println("COMPLETED remote call with callback SUCCESS with result="+result);
					System.out.println();
				}
				public void onFailure(Throwable t) {
					System.out.println("COMPLETED remote call with callback FAILED with exception="+t);
					System.out.println();
				}
			};
			
			// Call asynchronously with callback
			System.out.println("STARTING async remote call via callback...");
			helloA.helloAsync(CONSUMER_NAME + " via async proxy with listener", callback);
			System.out.println("LOCAL async invocation complete");
			System.out.println();
			
			// Call asynchronously with future
			System.out.println("STARTING async remote call via future...");
			Future<String> future = helloA.helloAsync(CONSUMER_NAME + " via async proxy with future");
			System.out.println("LOCAL async future invocation complete");
			System.out.println();
			try {
				while (!future.isDone()) {
					// do some other stuff
					System.out.println("LOCAL future not yet done...so we're doing other stuff while waiting for future to be done");
					Thread.sleep(200);
				}
				// Now it's done, so this will not block
				String result = future.get();
				System.out.println("COMPLETED remote call with future SUCCEEDED with result="+result);
				System.out.println();
			} catch (OperationCanceledException e) {
				System.out.println("COMPLETED remote call with callback CANCELLED with exception="+e);
				System.out.println();
				e.printStackTrace();
			} catch (InterruptedException e) {
				System.out.println("COMPLETED remote call with callback INTERRUPTED with exception="+e);
				System.out.println();
				e.printStackTrace();
			} catch (ExecutionException e) {
				System.out.println("COMPLETED remote call with callback INTERRUPTED with exception="+e);
				System.out.println();
				e.printStackTrace();
			}
			
			// Call other helloMessage method
			// Call asynchronously with callback
			System.out.println("STARTING async remote call via callback...");
			helloA.helloMessageAsync(new HelloMessage(CONSUMER_NAME + " via async proxy with listener","howdy"), callback);
			System.out.println("LOCAL async invocation complete");
			System.out.println();
			
			// Call asynchronously with future
			System.out.println("STARTING async remote call via future...");
			future = helloA.helloMessageAsync(new HelloMessage(CONSUMER_NAME + " via async proxy with future","howdy"));
			System.out.println("LOCAL async future invocation complete");
			System.out.println();
			try {
				while (!future.isDone()) {
					// do some other stuff
					System.out.println("LOCAL future not yet done...so we're doing other stuff while waiting for future to be done");
					Thread.sleep(200);
				}
				// Now it's done, so this will not block
				String result = future.get();
				System.out.println("COMPLETED remote call with future SUCCEEDED with result="+result);
				System.out.println();
			} catch (OperationCanceledException e) {
				System.out.println("COMPLETED remote call with callback CANCELLED with exception="+e);
				System.out.println();
				e.printStackTrace();
			} catch (InterruptedException e) {
				System.out.println("COMPLETED remote call with callback INTERRUPTED with exception="+e);
				System.out.println();
				e.printStackTrace();
			} catch (ExecutionException e) {
				System.out.println("COMPLETED remote call with callback INTERRUPTED with exception="+e);
				System.out.println();
				e.printStackTrace();
			}

		}
		
		// OSGi 4.2 remote service spec requires a property named 'service.imported' to be
		// set to a non-null value.  In the case of any ECF provider, this 'service.imported' property
		// is set to the IRemoteService object associated with the remote service.
		IRemoteService remoteService = (IRemoteService) reference
				.getProperty(IDistributionConstants.SERVICE_IMPORTED);
		Assert.isNotNull(remoteService);
		
		// This IRemoteService instance allows allows non-blocking/asynchronous invocation of
		// remote methods.  This allows the client to decide (at runtime if necessary) whether
		// to do synchronous/blocking calls or asynchronous/non-blocking calls.
		
		// It's also possible to get the remote service directly from the proxy
		remoteService = ((IRemoteServiceProxy) proxy).getRemoteService();
		Assert.isNotNull(remoteService);
		
		// In this case, we will make an non-blocking call and immediately get a 'future'...which is
		// a placeholder for a result of the remote computation.  This will not block.
		System.out.println("STARTING async remote call via future...");
		IFuture future = RemoteServiceHelper.futureExec(remoteService, "hello",
				new Object[] { CONSUMER_NAME + " future" });
		System.out.println("LOCAL async future invocation complete");
		// Client can execute arbitrary code here...
		try {
			// This blocks until communication and computation have completed successfully
			while (!future.isDone()) {
				// do some other stuff
				System.out.println("LOCAL future not yet done...so we're doing other stuff while waiting for future to be done");
				Thread.sleep(200);
			}
			// Now it's done, so this will not block
			Object result = future.get();
			System.out.println("COMPLETED remote call with future SUCCEEDED with result="+result);
			System.out.println();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return proxy;
	}

	public void modifiedService(ServiceReference reference, Object service) {
	}

	public void removedService(ServiceReference reference, Object service) {
		System.out.println("IHello Service proxy removed");
	}

}
