/*******************************************************************************
 * Copyright (c) 2010 Oracle.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution. 
 * The Eclipse Public License is available at
 *     http://www.eclipse.org/legal/epl-v10.html
 * and the Apache License v2.0 is available at 
 *     http://www.opensource.org/licenses/apache2.0.php.
 * You may elect to redistribute this code under either of these licenses.
 *
 * Contributors:
 *     Hal Hildebrand - Initial JMX support 
 ******************************************************************************/

package org.eclipse.gemini.mgmt.framework;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.management.Notification;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.jmx.framework.BundleStateMBean;

import org.eclipse.gemini.mgmt.Monitor;
import org.eclipse.gemini.mgmt.framework.internal.OSGiBundle;
import org.eclipse.gemini.mgmt.framework.internal.OSGiBundleEvent;
import org.eclipse.gemini.mgmt.internal.BundleUtil;

/** 
 * 
 */
public final class BundleState extends Monitor implements CustomBundleStateMBean {
	
	private BundleListener bundleListener;
	
	private BundleContext bundleContext;
	
	/**
	 * 
	 * @param bundleContext
	 */
	public BundleState(BundleContext bundleContext) {
		this.bundleContext = bundleContext;
	}

	/**
	 * {@inheritDoc}
	 */
	public TabularData listBundles() throws IOException {
		try {
			TabularDataSupport table = new TabularDataSupport(CustomBundleStateMBean.CUSTOM_BUNDLES_TYPE);
			for (Bundle bundle : bundleContext.getBundles()) {
				table.put(new OSGiBundle(bundle).asCompositeData());
			}
			return table;
		} catch (Throwable e) {
			throw new IOException(e);
		}
	}
	
	/**
	 * {@inheritDoc}
	 */
	public TabularData listBundles(int mask) throws IOException {
		if (mask < 1 || mask > 2097151) {
			throw new IllegalArgumentException("Mask out of range!");
		}
		try {
			ArrayList<OSGiBundle> bundles = new ArrayList<OSGiBundle>();
			for (Bundle bundle : bundleContext.getBundles()) {
				bundles.add(new OSGiBundle(bundle));
			}
			TabularData table = OSGiBundle.tableFrom(bundles, mask);
			return table;
		} catch (Throwable e) {
			throw new IOException(e);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public String[] getExportedPackages(long bundleId) throws IOException {
		return BundleUtil.getBundleExportedPackages(retrieveBundle(bundleId));
	}

	/**
	 * {@inheritDoc}
	 */
	public long[] getFragments(long bundleId) throws IOException {
		BundleWiring wiring = retrieveBundle(bundleId).adapt(BundleWiring.class);
		List<BundleWire> requiredWires = wiring.getRequiredWires(BundleRevision.HOST_NAMESPACE);
        return bundleWiresToIds(requiredWires);
	}

	/**
	 * {@inheritDoc}
	 */
	public TabularData getHeaders(long bundleId) throws IOException {
		return OSGiBundle.headerTable(retrieveBundle(bundleId).getHeaders());
	}

	/**
	 * {@inheritDoc}
	 */
	public long[] getHosts(long fragment) throws IOException {
		BundleWiring wiring = retrieveBundle(fragment).adapt(BundleWiring.class);
		List<BundleWire> providedWires = wiring.getProvidedWires(BundleRevision.HOST_NAMESPACE);
        return bundleWiresToIds(providedWires);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public String[] getImportedPackages(long bundleId) throws IOException {
		return BundleUtil.getBundleImportedPackages(retrieveBundle(bundleId));
	}

	/**
	 * {@inheritDoc}
	 */
	public long getLastModified(long bundleId) throws IOException {
		return retrieveBundle(bundleId).getLastModified();
	}

	/**
	 * {@inheritDoc}
	 */
	public long[] getRegisteredServices(long bundleId) throws IOException {
		return serviceIds(retrieveBundle(bundleId).getRegisteredServices());
	}

	/**
	 * {@inheritDoc}
	 */
	public long[] getRequiringBundles(long bundleId) throws IOException {
        BundleWiring wiring = retrieveBundle(bundleId).adapt(BundleWiring.class);
        List<BundleWire> providedWires = wiring.getProvidedWires(BundleRevision.BUNDLE_NAMESPACE);
        return bundleWiresToIds(providedWires);
    }
	/**
	 * {@inheritDoc}
	 */
	public long[] getServicesInUse(long bundleIdentifier) throws IOException {
		return serviceIds(retrieveBundle(bundleIdentifier).getServicesInUse());
	}

	/**
	 * {@inheritDoc}
	 */
	public int getStartLevel(long bundleId) throws IOException {
		return BundleUtil.getBundleStartLevel(retrieveBundle(bundleId));
	}

	/**
	 * {@inheritDoc}
	 */
	public String getState(long bundleId) throws IOException {
		return BundleUtil.getBundleState(retrieveBundle(bundleId));
	}

	/**
	 * {@inheritDoc}
	 */
	public String getSymbolicName(long bundleId) throws IOException {
		return retrieveBundle(bundleId).getSymbolicName();
	}

	/**
	 * {@inheritDoc}
	 */
	public String getLocation(long bundleId) throws IOException {
		return retrieveBundle(bundleId).getLocation();
	}

	/**
	 * {@inheritDoc}
	 */
	public long[] getRequiredBundles(long bundleIdentifier) throws IOException {
        BundleWiring wiring = retrieveBundle(bundleIdentifier).adapt(BundleWiring.class);
        List<BundleWire> requiredWires = wiring.getRequiredWires(BundleRevision.BUNDLE_NAMESPACE);
        return bundleWiresToIds(requiredWires);
    }

	/**
	 * {@inheritDoc}
	 */
	public String getVersion(long bundleId) throws IOException {
		return retrieveBundle(bundleId).getVersion().toString();
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isPersistentlyStarted(long bundleId) throws IOException {
		return BundleUtil.isBundlePersistentlyStarted(retrieveBundle(bundleId));
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isFragment(long bundleId) throws IOException {
		return BundleUtil.isBundleFragment(retrieveBundle(bundleId));
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isRemovalPending(long bundleId) throws IOException {
		return BundleUtil.isRemovalPending(retrieveBundle(bundleId));
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isRequired(long bundleId) throws IOException {
		return BundleUtil.isRequired(retrieveBundle(bundleId));
	}

	//New methods from the JMX Update RFC 169
	
	/**
	 * {@inheritDoc}
	 */
	public CompositeData getBundle(long bundleId) throws IOException {
		return new OSGiBundle(retrieveBundle(bundleId)).asCompositeData();
	}

	/**
	 * {@inheritDoc}
	 */
	public TabularData listBundles(String... bundleTypeItems) throws IOException {
		try {
			ArrayList<OSGiBundle> bundles = new ArrayList<OSGiBundle>();
			for (Bundle bundle : bundleContext.getBundles()) {
				bundles.add(new OSGiBundle(bundle));
			}
			TabularData table = OSGiBundle.tableFrom(bundles, bundleTypeItems);
			return table;
		} catch (Throwable e) {
			throw new IOException(e);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isActivationPolicyUsed(long bundleId) throws IOException {
		return BundleUtil.isBundleActivationPolicyUsed(retrieveBundle(bundleId));
	}

	/**
	 * {@inheritDoc}
	 */
	public String getHeader(long bundleId, String key) throws IOException {
		return retrieveBundle(bundleId).getHeaders().get(key);
	}

	/**
	 * {@inheritDoc}
	 */
	public TabularData getHeaders(long bundleId, String locale) throws IOException {
		return OSGiBundle.headerTable(retrieveBundle(bundleId).getHeaders(locale));
	}

	/**
	 * {@inheritDoc}
	 */
	public CompositeData getHeaders(long bundleId, String key, String locale) throws IOException {
		String value = retrieveBundle(bundleId).getHeaders(locale).get(key);
		if(value == null){
			return null;
		}
		return OSGiBundle.getHeaderCompositeData(key, value);
	}

	//End methods for the MBean
	
	private Bundle retrieveBundle(long bundleId) throws IOException {
		Bundle b = bundleContext.getBundle(bundleId);
		if (b == null) {
			throw new IOException("Bundle with id: " + bundleId + " does not exist");
		}
		return b;
	}

	private long[] bundleWiresToIds(List<BundleWire> wires){
        long[] consumerWirings = new long[wires.size()];
        int i = 0;
        for (BundleWire bundleWire : wires) {
            consumerWirings[i] = bundleWire.getRequirerWiring().getBundle().getBundleId();
            i++;
        }
        return consumerWirings;
	}

	private long[] serviceIds(ServiceReference<?>[] refs) {
		if (refs == null) {
			return new long[0];
		}
		long[] ids = new long[refs.length];
		for (int i = 0; i < refs.length; i++) {
			ids[i] = (Long) refs[i].getProperty(Constants.SERVICE_ID);
		}
		return ids;
	}
	
	//Monitor methods
	
	/**
	 * {@inheritDoc}
	 */
	protected void addListener() {
		bundleListener = getBundleListener();
		bundleContext.addBundleListener(bundleListener);
	}

	private BundleListener getBundleListener() {
		return new BundleListener() {
			public void bundleChanged(BundleEvent bundleEvent) {
				Notification notification = new Notification(BundleStateMBean.EVENT, objectName, sequenceNumber++);
				notification.setUserData(new OSGiBundleEvent(bundleEvent).asCompositeData());
				sendNotification(notification);
			}
		};
	}

	/**
	 * {@inheritDoc}
	 */
	protected void removeListener() {
		if (bundleListener != null) {
			bundleContext.removeBundleListener(bundleListener);
		}
	}

}
