/*******************************************************************************
 * Copyright (c) 2008, 2010 VMware Inc.
 * 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:
 *   VMware Inc. - initial contribution
 *******************************************************************************/

package org.eclipse.virgo.nano.core.internal;

import java.lang.management.ManagementFactory;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.management.ObjectName;

import org.eclipse.virgo.kernel.config.internal.ConfigurationInitialiser;
import org.eclipse.virgo.kernel.config.internal.KernelConfiguration;
import org.eclipse.virgo.nano.core.BundleStarter;
import org.eclipse.virgo.nano.core.Shutdown;
import org.eclipse.virgo.nano.core.internal.blueprint.ApplicationContextDependencyMonitor;
import org.eclipse.virgo.nano.serviceability.dump.internal.RegionDigraphDumpContributor;
import org.eclipse.virgo.nano.serviceability.dump.internal.ResolutionDumpContributor;
import org.eclipse.virgo.kernel.shim.scope.ScopeFactory;
import org.eclipse.virgo.kernel.shim.scope.internal.StandardScopeFactory;
import org.eclipse.virgo.kernel.shim.serviceability.TracingService;
import org.eclipse.virgo.kernel.shim.serviceability.internal.Slf4jTracingService;
import org.eclipse.virgo.medic.dump.DumpContributor;
import org.eclipse.virgo.medic.dump.DumpGenerator;
import org.eclipse.virgo.medic.eventlog.EventLogger;
import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.launch.Framework;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;

/**
 * ComponentContext activator that initialises the core of the Kernel.
 * 
 * <strong>Concurrent Semantics</strong><br />
 * Threadsafe.
 * 
 */
public class CoreBundleActivator {

    private static final String START_SIGNALLING_THREAD_NAME_PREFIX = "start-signalling-";

    private static final String PROPERTY_NAME_SERVICE_SCOPE = "org.eclipse.virgo.service.scope";
    
    private static final String SERVICE_SCOPE_GLOBAL = "global";

    private static final String EVENT_TOPIC_BLUEPRINT_CONTAINER = "org/osgi/service/blueprint/container/*";

    private static final String EVENT_TOPIC_REGION = "org/eclipse/virgo/kernel/region/*";
    
    private static final String MBEAN_VALUE_SHUTDOWN = "Shutdown";

    private static final String MBEAN_KEY_TYPE = "type";
    
    private final ServiceRegistrationTracker tracker = new ServiceRegistrationTracker();

    private final ConfigurationInitialiser configurationInitialiser = new ConfigurationInitialiser();

    private volatile StartupTracker startupTracker;

    private volatile ObjectInstance shutdownMBean;
    
    private volatile ApplicationContextDependencyMonitor dependencyMonitor;
    
    private volatile BundleStartTracker bundleStartTracker;

    public void activate(ComponentContext componentContext) throws Exception {
        BundleContext context = componentContext.getBundleContext();
        
        EventLogger eventLogger = getRequiredService(context, EventLogger.class);

        KernelConfiguration configuration = this.configurationInitialiser.start(context, eventLogger);
        Shutdown shutdown = initializeShutdownManager(context, eventLogger, configuration);
        
        this.bundleStartTracker = createAndRegisterBundleStartTracker(context);    	
        createAndRegisterBundleStarter(this.bundleStartTracker, context);
        
        this.dependencyMonitor = createAndRegisterApplicationContextDependencyMonitor(context, eventLogger);
        
        DumpGenerator dumpGenerator = getRequiredService(context, DumpGenerator.class);
        
        createAndRegisterStateDumpContributors(context);
        
        this.startupTracker = new StartupTracker(context, configuration, configuration.getStartupWaitLimit(), bundleStartTracker, shutdown, dumpGenerator);
        this.startupTracker.start();
        
        initShimServices(context, eventLogger);
    }
    
    private void createAndRegisterStateDumpContributors(BundleContext context) {
        this.tracker.track(context.registerService(DumpContributor.class, new ResolutionDumpContributor(context), null));
        this.tracker.track(context.registerService(DumpContributor.class, new RegionDigraphDumpContributor(context), null));
    }

    private ApplicationContextDependencyMonitor createAndRegisterApplicationContextDependencyMonitor(BundleContext context, EventLogger eventLogger) {
        ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(1, new ThreadFactory() {            
            private AtomicLong threadCount = new AtomicLong(1);

            public Thread newThread(Runnable r) {
                String name = "service-monitor-thread-" + this.threadCount.getAndIncrement();
                return new Thread(r, name);                
            }            
        });
        
        ApplicationContextDependencyMonitor dependencyMonitor = new ApplicationContextDependencyMonitor(scheduledExecutor, eventLogger);
        
        Dictionary<String, String> properties = new Hashtable<String, String>();
        properties.put(EventConstants.EVENT_TOPIC, EVENT_TOPIC_BLUEPRINT_CONTAINER);
        
        this.tracker.track(context.registerService(EventHandler.class.getName(), dependencyMonitor, properties));
        
       return dependencyMonitor;
    }

    @SuppressWarnings("unchecked")
    private BundleStartTracker createAndRegisterBundleStartTracker(BundleContext context) {
    	BlockingQueue q = new SynchronousQueue();
    	ThreadPoolExecutor executor = new ThreadPoolExecutor(1, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, q, new PrefixingThreadFactory(START_SIGNALLING_THREAD_NAME_PREFIX), new ThreadPoolExecutor.AbortPolicy());
    	BundleStartTracker asynchronousStartTracker = new BundleStartTracker(executor);
    	asynchronousStartTracker.initialize(context);
    	
    	Dictionary properties = new Hashtable();
        properties.put(EventConstants.EVENT_TOPIC, new String[] {EVENT_TOPIC_BLUEPRINT_CONTAINER, EVENT_TOPIC_REGION});        
        
        this.tracker.track(context.registerService(new String[] {EventHandler.class.getName()}, asynchronousStartTracker, properties));
        
        return asynchronousStartTracker;
    }

    @SuppressWarnings("unchecked")
    private BundleStarter createAndRegisterBundleStarter(BundleStartTracker asynchronousStartTracker, BundleContext bundleContext) {
    	
        StandardBundleStarter bundleStarter = new StandardBundleStarter(asynchronousStartTracker);
        Dictionary properties = new Hashtable();        
        properties.put(PROPERTY_NAME_SERVICE_SCOPE, SERVICE_SCOPE_GLOBAL);
        
        this.tracker.track(bundleContext.registerService(new String[] {BundleStarter.class.getName()}, bundleStarter, properties));
        
        return bundleStarter;
    }

    public void deactivate(ComponentContext context) throws Exception {
        this.tracker.unregisterAll();
        this.startupTracker.stop();
        this.configurationInitialiser.stop();
        
        unregisterShutdownMBean();
        
        ApplicationContextDependencyMonitor dependencyMonitor = this.dependencyMonitor;
        if (dependencyMonitor != null) {
            this.dependencyMonitor = null;
            dependencyMonitor.stop();
        }
        
        BundleStartTracker bundleStartTracker = this.bundleStartTracker;
        if (bundleStartTracker != null) {
            this.bundleStartTracker = null;
            bundleStartTracker.stop();
        }
    }

    private Shutdown initializeShutdownManager(BundleContext context, EventLogger eventLogger, KernelConfiguration configuration) {
        Shutdown shutdown = createShutdown(context, eventLogger);
        this.tracker.track(context.registerService(org.eclipse.virgo.nano.core.Shutdown.class.getName(), shutdown, null));

        registerShutdownMBean(configuration, shutdown);
        return shutdown;
    }

    private void registerShutdownMBean(KernelConfiguration configuration, Shutdown shutdown) {
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();

        try {
            ObjectName shutdownName = ObjectName.getInstance(configuration.getDomain(), MBEAN_KEY_TYPE, MBEAN_VALUE_SHUTDOWN);
            this.shutdownMBean = server.registerMBean(new AsyncShutdownDecorator(shutdown), shutdownName);
        } catch (JMException ex) {
            throw new IllegalStateException("Unable to register Shutdown MBean", ex);
        }
    }

    private void unregisterShutdownMBean() throws MBeanRegistrationException, InstanceNotFoundException {
        ObjectInstance localShutdownMBean = this.shutdownMBean;
        if (localShutdownMBean != null) {
            ManagementFactory.getPlatformMBeanServer().unregisterMBean(localShutdownMBean.getObjectName());
            this.shutdownMBean = null;
        }
    }

    protected Shutdown createShutdown(BundleContext context, EventLogger eventLogger) {
        Framework framework = (Framework) context.getBundle(0);

        ShutdownManager manager = new ShutdownManager(eventLogger, framework);
        return manager;
    }

    private void initShimServices(BundleContext context, EventLogger eventLogger) {
        ScopeFactory scopeFactory = new StandardScopeFactory(eventLogger);
        TracingService tracingService = new Slf4jTracingService();
        this.tracker.track(context.registerService(ScopeFactory.class.getName(), scopeFactory, null));
        this.tracker.track(context.registerService(TracingService.class.getName(), tracingService, null));
    }

    @SuppressWarnings("unchecked")
    private <T> T getRequiredService(BundleContext context, Class<T> clazz) {
        T result = null;
        ServiceReference ref = context.getServiceReference(clazz.getName());
        if (ref != null) {
            result = (T) context.getService(ref);
        }
        if (result == null) {
            throw new IllegalStateException("Unable to access required service of type '" + clazz.getName() + "' from bundle '"
                + context.getBundle().getSymbolicName() + "'");
        }
        return result;
    }
    
    private class PrefixingThreadFactory implements ThreadFactory {
		private int threadCount = 0;
		private final Object threadCountMonitor = new Object();
		String prefix = "default-thread-prefix";
		
		public PrefixingThreadFactory(String prefix) {
			this.prefix = prefix;
		}
		
		@Override
		public Thread newThread(Runnable r) {
			return new Thread(r, nextThreadName());
		}
		
		private String nextThreadName() {
			int threadNumber = 0;
			synchronized (this.threadCountMonitor) {
				this.threadCount++;
				threadNumber = this.threadCount;
			}
			return this.prefix + threadNumber;
		}
	}
}
