/*******************************************************************************
 * Copyright (c) 2012, 2016 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.osgi.container;

import java.util.Collections;
import java.util.EnumSet;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.osgi.container.ModuleContainer.ContainerStartLevel;
import org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent;
import org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent;
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.report.resolution.ResolutionReport;
import org.osgi.framework.AdminPermission;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.launch.Framework;
import org.osgi.service.resolver.ResolutionException;

/**
 * A special kind of module that represents the system module for the container.  Additional
 * methods are available on the system module for operations that effect the whole container.
 * For example, initializing the container, restarting and waiting for the container to stop.
 * @since 3.10
 */
public abstract class SystemModule extends Module {
	private volatile AtomicReference<ContainerEvent> forStop = new AtomicReference<>();

	public SystemModule(ModuleContainer container) {
		super(new Long(0), Constants.SYSTEM_BUNDLE_LOCATION, container, EnumSet.of(Settings.AUTO_START, Settings.USE_ACTIVATION_POLICY), Integer.valueOf(0));
	}

	/**
	 * Initializes the module container
	 * @throws BundleException if an exeption occurred while initializing
	 */
	public final void init() throws BundleException {
		getRevisions().getContainer().checkAdminPermission(getBundle(), AdminPermission.EXECUTE);

		boolean lockedStarted = false;
		// Indicate we are in the middle of a start.
		// This must be incremented before we acquire the STARTED lock the first time.
		inStart.incrementAndGet();
		try {
			lockStateChange(ModuleEvent.STARTED);
			lockedStarted = true;
			getContainer().getAdaptor().initBegin();
			checkValid();
			if (ACTIVE_SET.contains(getState()))
				return;
			getRevisions().getContainer().open();
			if (getState().equals(State.INSTALLED)) {
				// must unlock to avoid out of order locks when multiple unresolved
				// bundles are started at the same time from different threads
				unlockStateChange(ModuleEvent.STARTED);
				lockedStarted = false;
				ResolutionReport report;
				try {
					report = getRevisions().getContainer().resolve(Collections.singletonList((Module) this), true);
				} finally {
					lockStateChange(ModuleEvent.STARTED);
					lockedStarted = true;
				}
				// need to check valid again in case someone uninstalled the bundle
				checkValid();
				ResolutionException e = report.getResolutionException();
				if (e != null) {
					if (e.getCause() instanceof BundleException) {
						throw (BundleException) e.getCause();
					}
				}
				if (ACTIVE_SET.contains(getState()))
					return;
				if (getState().equals(State.INSTALLED)) {
					String reportMessage = report.getResolutionReportMessage(getCurrentRevision());
					throw new BundleException(Msg.Module_ResolveError + reportMessage, BundleException.RESOLVE_ERROR);
				}
			}

			setState(State.STARTING);
			AtomicReference<ContainerEvent> existingForStop = forStop;
			if (existingForStop.get() != null) {
				// There was a previous launch, reset the reference forStop
				forStop = new AtomicReference<>();
			}
			publishEvent(ModuleEvent.STARTING);
			try {
				initWorker();
			} catch (Throwable t) {
				setState(State.STOPPING);
				publishEvent(ModuleEvent.STOPPING);
				setState(State.RESOLVED);
				publishEvent(ModuleEvent.STOPPED);
				getRevisions().getContainer().close();
				if (t instanceof BundleException) {
					throw (BundleException) t;
				}
				throw new BundleException("Error initializing container.", BundleException.ACTIVATOR_ERROR, t); //$NON-NLS-1$
			}
		} finally {
			getContainer().getAdaptor().initEnd();
			if (lockedStarted) {
				unlockStateChange(ModuleEvent.STARTED);
			}
			inStart.decrementAndGet();
		}
	}

	/**
	 * Waits until the module container has stopped.
	 * @param timeout The amount of time to wait.
	 * @return The container event indicated why the framework stopped
	 * or if there was a time out waiting for stop.
	 * @see Framework#waitForStop(long)
	 * @throws InterruptedException if the thread was interrupted while waiting
	 */
	public ContainerEvent waitForStop(long timeout) throws InterruptedException {
		final boolean waitForever = timeout == 0;
		final long start = System.currentTimeMillis();
		long timeLeft = timeout;
		AtomicReference<ContainerEvent> stopEvent = null;
		State currentState = null;
		boolean stateLocked = false;
		try {
			if (timeout == 0) {
				stateChangeLock.lockInterruptibly();
				stateLocked = true;
			} else {
				stateLocked = stateChangeLock.tryLock(timeLeft, TimeUnit.MILLISECONDS);
			}
			if (stateLocked) {
				stopEvent = forStop;
				currentState = getState();
			}
		} finally {
			if (stateLocked) {
				stateChangeLock.unlock();
			}
		}

		if (stopEvent == null || currentState == null) {
			// Could not lock system module stateChangeLock; timeout
			return ContainerEvent.STOPPED_TIMEOUT;
		}
		if (!ACTIVE_SET.contains(currentState)) {
			// check if a past event is waiting for us
			ContainerEvent result = stopEvent.get();
			if (result != null) {
				return result;
			}
			// framework must not have even been started yet
			return ContainerEvent.STOPPED;
		}
		synchronized (stopEvent) {
			do {
				ContainerEvent result = stopEvent.get();
				if (result != null) {
					return result;
				}
				timeLeft = waitForever ? 0 : start + timeout - System.currentTimeMillis();
				if (waitForever || timeLeft > 0) {
					stopEvent.wait(timeLeft);
				} else {
					return ContainerEvent.STOPPED_TIMEOUT;
				}
			} while (true);
		}
	}

	/**
	 * @throws BundleException
	 */
	protected void initWorker() throws BundleException {
		// Do nothing
	}

	@Override
	public void start(StartOptions... options) throws BundleException {
		// make sure to init if needed
		init();
		// Always transient
		super.start(StartOptions.TRANSIENT, StartOptions.USE_ACTIVATION_POLICY);
		getRevisions().getContainer().adaptor.publishContainerEvent(ContainerEvent.STARTED, this, null);
	}

	@Override
	public void stop(StopOptions... options) throws BundleException {
		ContainerEvent containerEvent = ContainerEvent.STOPPED_TIMEOUT;
		// Need to lock the state change lock with no state to prevent
		// other threads from starting the framework while we are shutting down
		try {
			if (stateChangeLock.tryLock(10, TimeUnit.SECONDS)) {
				try {
					try {
						// Always transient
						super.stop(StopOptions.TRANSIENT);
					} catch (BundleException e) {
						getRevisions().getContainer().adaptor.publishContainerEvent(ContainerEvent.ERROR, this, e);
						// must continue on
					}
					if (holdsTransitionEventLock(ModuleEvent.UPDATED)) {
						containerEvent = ContainerEvent.STOPPED_UPDATE;
					} else if (holdsTransitionEventLock(ModuleEvent.UNRESOLVED)) {
						containerEvent = ContainerEvent.STOPPED_REFRESH;
					} else {
						containerEvent = ContainerEvent.STOPPED;
					}
					getRevisions().getContainer().adaptor.publishContainerEvent(containerEvent, this, null);
					getRevisions().getContainer().close();
				} finally {
					AtomicReference<ContainerEvent> eventReference = forStop;
					eventReference.compareAndSet(null, containerEvent);
					stateChangeLock.unlock();
					synchronized (eventReference) {
						eventReference.notifyAll();
					}
				}
			} else {
				throw new BundleException(Msg.SystemModule_LockError);
			}
		} catch (InterruptedException e) {
			getRevisions().getContainer().adaptor.publishContainerEvent(ContainerEvent.ERROR, this, e);
			throw new BundleException(Msg.Module_LockError + toString(), BundleException.STATECHANGE_ERROR, e);
		}

	}

	/**
	 * Restarts the module container.
	 * @see Framework#update()
	 * @throws BundleException
	 */
	public void update() throws BundleException {
		getContainer().checkAdminPermission(getBundle(), AdminPermission.LIFECYCLE);
		State previousState;
		lockStateChange(ModuleEvent.UPDATED);
		try {
			previousState = getState();
			stop();
		} finally {
			unlockStateChange(ModuleEvent.UPDATED);
		}
		// would publish an updated event here but the listener services are down
		switch (previousState) {
			case STARTING :
				init();
				break;
			case ACTIVE :
				start();
			default :
				break;
		}
	}

	@Override
	protected void startWorker() throws BundleException {
		super.startWorker();
		((ContainerStartLevel) getRevisions().getContainer().getFrameworkStartLevel()).doContainerStartLevel(this, ContainerStartLevel.USE_BEGINNING_START_LEVEL);
	}

	@Override
	protected void stopWorker() throws BundleException {
		super.stopWorker();
		((ContainerStartLevel) getRevisions().getContainer().getFrameworkStartLevel()).doContainerStartLevel(this, 0);
	}
}
