/*******************************************************************************
 * Copyright (c) 2005, 2018 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.equinox.internal.app;

import java.net.URL;
import java.security.AccessController;
import java.util.*;
import org.eclipse.equinox.app.IApplicationContext;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.application.*;
import org.osgi.service.condpermadmin.BundleSignerCondition;
import org.osgi.service.condpermadmin.ConditionInfo;

/*
 * An ApplicationDescriptor for an eclipse application.
 */
public class EclipseAppDescriptor extends ApplicationDescriptor {
	static final String APP_TYPE = "eclipse.application.type"; //$NON-NLS-1$
	static final String APP_DEFAULT = "eclipse.application.default"; //$NON-NLS-1$
	static final String APP_TYPE_MAIN_THREAD = "main.thread"; //$NON-NLS-1$
	static final String APP_TYPE_ANY_THREAD = "any.thread"; //$NON-NLS-1$
	static final int FLAG_VISIBLE = 0x01;
	static final int FLAG_CARD_SINGLETON_GLOGAL = 0x02;
	static final int FLAG_CARD_SINGLETON_SCOPED = 0x04;
	static final int FLAG_CARD_UNLIMITED = 0x08;
	static final int FLAG_CARD_LIMITED = 0x10;
	static final int FLAG_TYPE_MAIN_THREAD = 0x20;
	static final int FLAG_TYPE_ANY_THREAD = 0x40;
	static final int FLAG_DEFAULT_APP = 0x80;
	private long instanceID = 0;
	private ServiceRegistration sr;
	private Boolean locked = Boolean.FALSE;
	private final EclipseAppContainer appContainer;
	private final Bundle contributor;
	private final int flags;
	private final int cardinality;
	private final String name;
	private final URL iconURL;
	private final boolean[] registrationLock = new boolean[] {true};

	protected EclipseAppDescriptor(Bundle contributor, String pid, String name, String iconPath, int flags, int cardinality, EclipseAppContainer appContainer) {
		super(pid);
		this.name = name;
		this.contributor = contributor;
		this.appContainer = appContainer;
		this.locked = AppPersistence.isLocked(this) ? Boolean.TRUE : Boolean.FALSE;
		this.flags = flags;
		this.cardinality = cardinality;
		URL iconResult = null;
		// this bit of code is complex because we want to search fragments;
		// that can only be done by using the Bundle.findEntries method which
		// requires the path to be split up between the base and the file name!!
		if (iconPath != null && iconPath.length() > 0) {
			if (iconPath.charAt(0) == '/')
				iconPath = iconPath.substring(1);
			String baseIconDir = "/"; //$NON-NLS-1$
			String iconFile = iconPath;
			int lastSlash = iconPath.lastIndexOf('/');
			if (lastSlash > 0 && lastSlash < iconPath.length() - 1) {
				baseIconDir = iconPath.substring(0, lastSlash);
				iconFile = iconPath.substring(lastSlash + 1);
			}
			Enumeration<URL> urls = contributor.findEntries(baseIconDir, iconFile, false);
			if (urls != null && urls.hasMoreElements())
				iconResult = urls.nextElement();
		}
		this.iconURL = iconResult;
	}

	@Override
	protected Map getPropertiesSpecific(String locale) {
		// just use the service properties; for now we do not localize any properties
		return getServiceProperties();
	}

	@Override
	protected ApplicationHandle launchSpecific(Map arguments) throws Exception {
		// if this application is locked throw an exception.
		if (getLocked().booleanValue())
			throw new IllegalStateException("Cannot launch a locked application."); //$NON-NLS-1$
		// initialize the appHandle
		EclipseAppHandle appHandle = createAppHandle(arguments);
		try {
			// use the appContainer to launch the application on the main thread.
			appContainer.launch(appHandle);
		} catch (Throwable t) {
			// be sure to destroy the appHandle if an error occurs
			try {
				appHandle.destroy();
			} catch (Throwable destroyError) {
				// ignore and clean up
			}
			if (t instanceof Exception)
				throw (Exception) t;
			throw (Error) t;
		}
		return appHandle;
	}

	@Override
	protected synchronized void lockSpecific() {
		locked = Boolean.TRUE;
		// make sure the service properties are updated with the latest lock info
		refreshProperties();
	}

	@Override
	protected synchronized void unlockSpecific() {
		locked = Boolean.FALSE;
		// make sure the service properties are updated with the latest lock info
		refreshProperties();
	}

	void refreshProperties() {
		ServiceRegistration reg = getServiceRegistration();
		if (reg != null)
			try {
				reg.setProperties(getServiceProperties());
			} catch (IllegalStateException e) {
				// this must mean the service was unregistered
				// just ignore
			}
	}

	void setServiceRegistration(ServiceRegistration sr) {
		synchronized (registrationLock) {
			this.sr = sr;
			registrationLock[0] = sr != null;
			registrationLock.notifyAll();
		}

	}

	private ServiceRegistration getServiceRegistration() {
		synchronized (registrationLock) {
			if (sr == null && registrationLock[0])
				try {
					registrationLock.wait(1000); // timeout after 1 second
				} catch (InterruptedException e) {
					// nothing
				}
			return sr;
		}
	}

	private synchronized Boolean getLocked() {
		return locked;
	}

	/*
	 * Gets a snapshot of the current service properties.
	 */
	Hashtable<String, Object> getServiceProperties() {
		Hashtable<String, Object> props = new Hashtable<>(10);
		props.put(ApplicationDescriptor.APPLICATION_PID, getApplicationId());
		if (name != null)
			props.put(ApplicationDescriptor.APPLICATION_NAME, name);
		props.put(ApplicationDescriptor.APPLICATION_CONTAINER, Activator.PI_APP);
		props.put(ApplicationDescriptor.APPLICATION_LOCATION, getLocation());
		Boolean launchable = appContainer.isLocked(this) == 0 ? Boolean.TRUE : Boolean.FALSE;
		props.put(ApplicationDescriptor.APPLICATION_LAUNCHABLE, launchable);
		props.put(ApplicationDescriptor.APPLICATION_LOCKED, getLocked());
		Boolean visible = (flags & FLAG_VISIBLE) != 0 ? Boolean.TRUE : Boolean.FALSE;
		props.put(ApplicationDescriptor.APPLICATION_VISIBLE, visible);
		props.put(APP_TYPE, getThreadTypeString());
		if ((flags & FLAG_DEFAULT_APP) != 0)
			props.put(APP_DEFAULT, Boolean.TRUE);
		if (iconURL != null)
			props.put(ApplicationDescriptor.APPLICATION_ICON, iconURL);
		return props;
	}

	private String getLocation() {
		if (contributor == null)
			return ""; //$NON-NLS-1$
		return Activator.getLocation(contributor);
	}

	/*
	 * Returns the appHandle.  If it does not exist then one is created.
	 */
	private EclipseAppHandle createAppHandle(Map<String, Object> arguments) throws ApplicationException {
		EclipseAppHandle newAppHandle = new EclipseAppHandle(getInstanceID(), arguments, this);
		appContainer.lock(newAppHandle);
		ServiceRegistration appHandleReg = (ServiceRegistration) AccessController.doPrivileged(appContainer.getRegServiceAction(new String[] {ApplicationHandle.class.getName(), IApplicationContext.class.getName()}, newAppHandle, newAppHandle.getServiceProperties()));
		newAppHandle.setServiceRegistration(appHandleReg);
		return newAppHandle;
	}

	EclipseAppContainer getContainerManager() {
		return appContainer;
	}

	@Override
	public boolean matchDNChain(String pattern) {
		if (contributor == null)
			return false;
		return BundleSignerCondition.getCondition(contributor, new ConditionInfo(BundleSignerCondition.class.getName(), new String[] {pattern})).isSatisfied();
	}

	@Override
	protected boolean isLaunchableSpecific() {
		return true;
	}

	public void unregister() {
		ServiceRegistration temp = getServiceRegistration();
		if (temp != null) {
			setServiceRegistration(null);
			temp.unregister();
		}
	}

	String getThreadTypeString() {
		if ((flags & FLAG_TYPE_ANY_THREAD) != 0)
			return APP_TYPE_ANY_THREAD;
		return APP_TYPE_MAIN_THREAD;
	}

	int getThreadType() {
		return flags & (FLAG_TYPE_ANY_THREAD | FLAG_TYPE_MAIN_THREAD);
	}

	int getCardinalityType() {
		return flags & (FLAG_CARD_SINGLETON_GLOGAL | FLAG_CARD_SINGLETON_SCOPED | FLAG_CARD_LIMITED | FLAG_CARD_UNLIMITED);
	}

	int getCardinality() {
		return cardinality;
	}

	private synchronized String getInstanceID() {
		// make sure the instanceID has not reached the max
		if (instanceID == Long.MAX_VALUE)
			instanceID = 0;
		// create a unique instance id
		return getApplicationId() + "." + instanceID++; //$NON-NLS-1$
	}
}
