/*******************************************************************************
 * Copyright (c) 2005, 2014 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.core.runtime.internal.adaptor;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.eclipse.core.runtime.adaptor.EclipseStarter;
import org.eclipse.osgi.framework.log.FrameworkLog;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.service.runnable.*;
import org.osgi.framework.*;
import org.osgi.framework.launch.Framework;

public class EclipseAppLauncher implements ApplicationLauncher {
	volatile private ParameterizedRunnable runnable = null;
	private Object appContext = null;
	private final java.util.concurrent.Semaphore runningLock = new java.util.concurrent.Semaphore(1);
	private final java.util.concurrent.Semaphore waitForAppLock = new java.util.concurrent.Semaphore(0);
	private final BundleContext context;
	private boolean relaunch = false;
	private final boolean failOnNoDefault;
	private final FrameworkLog log;
	private final EquinoxConfiguration equinoxConfig;

	public EclipseAppLauncher(BundleContext context, boolean relaunch, boolean failOnNoDefault, FrameworkLog log, EquinoxConfiguration equinoxConfig) {
		this.context = context;
		this.relaunch = relaunch;
		this.failOnNoDefault = failOnNoDefault;
		this.log = log;
		this.equinoxConfig = equinoxConfig;
		findRunnableService();
	}

	/*
	 * Used for backwards compatibility with < 3.2 runtime
	 */
	private void findRunnableService() {
		// look for a ParameterizedRunnable registered as a service by runtimes (3.0, 3.1)
		String appClass = ParameterizedRunnable.class.getName();
		ServiceReference<?>[] runRefs = null;
		try {
			runRefs = context.getServiceReferences(ParameterizedRunnable.class.getName(), "(&(objectClass=" + appClass + ")(eclipse.application=*))"); //$NON-NLS-1$//$NON-NLS-2$
		} catch (InvalidSyntaxException e) {
			// ignore this.  It should never happen as we have tested the above format.
		}
		if (runRefs != null && runRefs.length > 0) {
			// found the service use it as the application.
			runnable = (ParameterizedRunnable) context.getService(runRefs[0]);
			// we will never be able to relaunch with a pre 3.2 runtime
			relaunch = false;
			waitForAppLock.release();
		}
	}

	/*
	 * Starts this application launcher on the current thread.  This method
	 * should be called by the main thread to ensure that applications are 
	 * launched in the main thread.
	 */
	public Object start(Object defaultContext) throws Exception {
		// here we assume that launch has been called by runtime before we started
		// TODO this may be a bad assumption but it works for now because we register the app launcher as a service and runtime synchronously calls launch on the service
		if (failOnNoDefault && runnable == null)
			throw new IllegalStateException(Msg.ECLIPSE_STARTUP_ERROR_NO_APPLICATION);
		Object result = null;
		boolean doRelaunch;
		Bundle b = context.getBundle();
		do {
			try {
				if (relaunch) {
					// need a thread to kick the main thread when the framework stops
					final Thread mainThread = Thread.currentThread();
					final BundleContext mainContext = context;
					new Thread(new Runnable() {
						@Override
						public void run() {
							Framework framework = (Framework) mainContext.getBundle(Constants.SYSTEM_BUNDLE_LOCATION);
							try {
								framework.waitForStop(0);
								// framework is done; tell the main thread to stop
								mainThread.interrupt();
							} catch (InterruptedException e) {
								Thread.interrupted();
								// just exiting now
							}
						}
					}, "Framework watcher").start(); //$NON-NLS-1$

				}
				result = runApplication(defaultContext);
			} catch (Exception e) {
				if (!relaunch || (b.getState() & Bundle.ACTIVE) == 0)
					throw e;
				if (log != null)
					log.log(new FrameworkLogEntry(EquinoxContainer.NAME, FrameworkLogEntry.ERROR, 0, Msg.ECLIPSE_STARTUP_APP_ERROR, 1, e, null));
			}
			doRelaunch = (relaunch && (b.getState() & Bundle.ACTIVE) != 0);
		} while (doRelaunch);
		return result;
	}

	/*
	 * Waits for an application to be launched and the runs the application on the
	 * current thread (main).
	 */
	private Object runApplication(Object defaultContext) throws Exception {
		try {
			// wait for an application to be launched.
			waitForAppLock.acquire();
			// an application is ready; acquire the running lock.
			// this must happen after we have acquired an application (by acquiring waitForAppLock above).
			runningLock.acquire();
			if (EclipseStarter.debug) {
				String timeString = equinoxConfig.getConfiguration("eclipse.startTime"); //$NON-NLS-1$ 
				long time = timeString == null ? 0L : Long.parseLong(timeString);
				Debug.println("Starting application: " + (System.currentTimeMillis() - time)); //$NON-NLS-1$ 
			}
			try {
				// run the actual application on the current thread (main).
				return runnable.run(appContext != null ? appContext : defaultContext);
			} finally {
				// free the runnable application and release the lock to allow another app to be launched.
				runnable = null;
				appContext = null;
				runningLock.release();
			}
		} catch (InterruptedException e) {
			// ignore; but mark interrupted for others
			Thread.interrupted();
		}
		return null;
	}

	public void launch(ParameterizedRunnable app, Object applicationContext) {
		waitForAppLock.tryAcquire(); // clear out any pending apps notifications
		if (!runningLock.tryAcquire()) // check to see if an application is currently running
			throw new IllegalStateException("An application is aready running."); //$NON-NLS-1$
		this.runnable = app;
		this.appContext = applicationContext;
		waitForAppLock.release(); // notify the main thread to launch an application.
		runningLock.release(); // release the running lock
	}

	public void shutdown() {
		// this method will aquire and keep the runningLock to prevent
		// all future application launches.
		if (runningLock.tryAcquire())
			return; // no application is currently running.
		ParameterizedRunnable currentRunnable = runnable;
		if (currentRunnable instanceof ApplicationRunnable) {
			((ApplicationRunnable) currentRunnable).stop();
			try {
				runningLock.tryAcquire(1, TimeUnit.MINUTES); // timeout after 1 minute.
			} catch (InterruptedException e) {
				// ignore
				Thread.interrupted();
			}
		}
	}

	/*
	 * Similar to the start method this method will restart the default method on current thread.
	 * This method assumes that the default application was launched at least once and that an ApplicationDescriptor 
	 * exists that can be used to relaunch the default application.
	 */
	public Object reStart(Object argument) throws Exception {
		ServiceReference<?> ref[] = null;
		ref = context.getServiceReferences("org.osgi.service.application.ApplicationDescriptor", "(eclipse.application.default=true)"); //$NON-NLS-1$//$NON-NLS-2$
		if (ref != null && ref.length > 0) {
			Object defaultApp = context.getService(ref[0]);
			Method launch = defaultApp.getClass().getMethod("launch", new Class[] {Map.class}); //$NON-NLS-1$
			launch.invoke(defaultApp, new Object[] {null});
			return start(argument);
		}
		throw new IllegalStateException(Msg.ECLIPSE_STARTUP_ERROR_NO_APPLICATION);
	}
}
