/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.aries.cdi.container.internal.container;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.enterprise.inject.spi.Extension;

import org.apache.aries.cdi.container.internal.container.Op.Mode;
import org.apache.aries.cdi.container.internal.container.Op.Type;
import org.apache.aries.cdi.container.internal.loader.BundleResourcesLoader;
import org.apache.aries.cdi.container.internal.model.ExtendedExtensionDTO;
import org.apache.aries.cdi.container.internal.model.FactoryComponent;
import org.apache.aries.cdi.container.internal.model.SingleComponent;
import org.apache.aries.cdi.container.internal.util.Syncro;
import org.jboss.weld.bootstrap.WeldBootstrap;
import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
import org.jboss.weld.bootstrap.spi.Deployment;
import org.jboss.weld.bootstrap.spi.Metadata;
import org.jboss.weld.util.ServiceLoader;
import org.osgi.service.log.Logger;

public class ContainerBootstrap extends Phase {

	public ContainerBootstrap(
		ContainerState containerState,
		ConfigurationListener.Builder configurationBuilder,
		SingleComponent.Builder singleBuilder,
		FactoryComponent.Builder factoryBuilder) {

		super(containerState, null);

		_configurationBuilder = configurationBuilder;
		_singleBuilder = singleBuilder;
		_factoryBuilder = factoryBuilder;
		_log = containerState.containerLogs().getLogger(getClass());
	}

	@Override
	public boolean close() {
		try (Syncro syncro = _lock.open()) {
			if (_bootstrap != null) {
				_log.debug(l -> l.debug("CCR container bootstrap shutdown on {}", _bootstrap));
				_bootstrap.shutdown();
				_bootstrap = null;
			}

			return true;
		}
		catch (Throwable t) {
			_log.error(l -> l.error("CCR Failure in container bootstrap shutdown on {}", _bootstrap, t));

			return false;
		}
	}

	@Override
	public Op closeOp() {
		return Op.of(Mode.CLOSE, Type.CONTAINER_BOOTSTRAP, containerState.id());
	}

	@Override
	public boolean open() {
		try (Syncro syncro = _lock.open()) {
			if (containerState.bundleContext() == null) {
				// this bundle was already removed
				return false;
			}

			if (_bootstrap != null) {
				return true;
			}

			if (containerState.containerDTO().components.isEmpty()) {
				return false;
			}

			List<Metadata<Extension>> extensions = new CopyOnWriteArrayList<>();

			// Add the internal extensions
			extensions.add(
				new ExtensionMetadata(
					new BundleContextExtension(containerState.bundleContext()),
					containerState.id()));
			extensions.add(
				new ExtensionMetadata(
					new RuntimeExtension(containerState, _configurationBuilder, _singleBuilder, _factoryBuilder),
					containerState.id()));
			extensions.add(
				new ExtensionMetadata(
					new LoggerExtension(containerState),
					containerState.id()));

			Thread currentThread = Thread.currentThread();
			ClassLoader current = currentThread.getContextClassLoader();
			BundleResourcesLoader.Builder builder = new BundleResourcesLoader.Builder(containerState.bundle(), containerState.extenderBundle());

			try {
				currentThread.setContextClassLoader(containerState.classLoader());

				// Add extensions found from the bundle's class loader, such as those in the Bundle-ClassPath
				ServiceLoader.load(Extension.class, containerState.classLoader()).forEach(extensions::add);

				// Add external extensions
				containerState.containerDTO().extensions.stream().map(
					ExtendedExtensionDTO.class::cast
				).map(
					e -> {
						builder.add(e.serviceReference.getBundle());
						return new ExtensionMetadata(e.extension.getService(), e.template.serviceFilter);
					}
				).forEach(extensions::add);

				_bootstrap = new WeldBootstrap();

				BeanDeploymentArchive beanDeploymentArchive = new ContainerDeploymentArchive(
					builder.build(),
					containerState.id(),
					containerState.beansModel().getBeanClassNames(),
					containerState.beansModel().getBeansXml());

				Deployment deployment = new ContainerDeployment(extensions, beanDeploymentArchive);

				_bootstrap.startExtensions(extensions);
				_bootstrap.startContainer(containerState.id(), new ContainerEnvironment(), deployment);
				_bootstrap.startInitialization();
				_bootstrap.deployBeans();
				_bootstrap.validateBeans();
				_bootstrap.endInitialization();
			}
			finally {
				currentThread.setContextClassLoader(current);
			}

			return true;
		}
	}

	@Override
	public Op openOp() {
		return Op.of(Mode.OPEN, Type.CONTAINER_BOOTSTRAP, containerState.id());
	}


	private volatile WeldBootstrap _bootstrap;
	private final ConfigurationListener.Builder _configurationBuilder;
	private final FactoryComponent.Builder _factoryBuilder;
	private final SingleComponent.Builder _singleBuilder;
	private final Syncro _lock = new Syncro(true);
	private final Logger _log;

}