/**
 * Copyright (c) 2008 IBM Corporation and others.
 * 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:
 * IBM Corporation - initial API and implementation
 */
package org.eclipse.egf.core.session;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IRegistryEventListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.RegistryFactory;
import org.eclipse.egf.common.helper.BundleHelper;
import org.eclipse.egf.common.helper.JavaHelper;
import org.eclipse.egf.common.helper.ObjectHolder;
import org.eclipse.egf.core.EGFCoreDebug;
import org.eclipse.egf.core.EGFCorePlugin;
import org.eclipse.egf.core.l10n.EGFCoreMessages;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.osgi.baseadaptor.BaseData;
import org.eclipse.osgi.framework.internal.core.AbstractBundle;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.BundleSpecification;
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.PluginRegistry;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.PackageAdmin;

/**
 * @author Xavier Maysonnave
 * 
 */
public final class ProjectBundleSession {

    private static final String EGF_TARGET_BUNDLE_PRIORITY = "egf.target.bundle.priority"; //$NON-NLS-1$

    public static String PROJECT_BUNDLE_SESSION = "org.eclipse.egf.core.project.bundle.session"; //$NON-NLS-1$

    private BundleContext context;

    private Map<String, Bundle> projectBundles = new HashMap<String, Bundle>();

    private List<String> uninstalled = new UniqueEList<String>();

    private Boolean runtimeBundlePriority;

    public static String getLocation(IPluginModelBase model) throws CoreException {
        if (model == null) {
            return null;
        }
        IResource resource = model.getUnderlyingResource();
        if (resource == null) {
            return null;
        }
        String location = null;
        try {
            location = "reference:" //$NON-NLS-1$
                    + URLDecoder.decode(resource.getProject().getLocationURI().toURL().toExternalForm(), System.getProperty("file.encoding")); //$NON-NLS-1$
        } catch (Throwable t) {
            throw new CoreException(EGFCorePlugin.getDefault().newStatus(IStatus.ERROR, NLS.bind(EGFCoreMessages.ProjectBundleSession_URLFailure, resource.getProject().getName()), t));
        }
        return location;
    }

    public ProjectBundleSession(BundleContext context) {
        Assert.isNotNull(context);
        this.context = context;
    }

    private void installWorkspaceModels(List<Bundle> bundles, List<IPluginModelBase> workspaceModels) throws CoreException {
        if (bundles == null || workspaceModels == null || workspaceModels.size() == 0) {
            return;
        }
        // Install Workspace models
        for (IPluginModelBase workspaceModel : workspaceModels) {
            // Ignore already installed bundle
            if (projectBundles.get(getLocation(workspaceModel)) != null) {
                continue;
            }
            // Retrieve base location
            String location = getLocation(workspaceModel);
            // Install the bundle
            Bundle bundle = installBundle(location);
            // Add output folders if any
            IProject project = workspaceModel.getUnderlyingResource().getProject();
            addOutputFoldersToBundleClasspath(project, bundle);
            // Store
            bundles.add(bundle);
            if (EGFCoreDebug.isDebugBundleSession()) {
                if (uninstalled.size() == 0 && projectBundles.size() == 0) {
                    EGFCorePlugin.getDefault().logInfo("Start ProjectBundleSession..."); //$NON-NLS-1$
                }
            }
            projectBundles.put(location, bundle);
        }
    }

    /**
     * Installs the bundle corresponding to the model.
     * 
     * @param model
     *            Model of the bundle to be installed.
     */
    private Bundle installBundle(IPluginModelBase model) throws CoreException {

        // We only load workspace model
        if (getLocation(model) == null) {
            return null;
        }

        final String bundleId = BundleHelper.getBundleId(model);
        if (bundleId == null) {
            return null;
        }

        // Gather workspace bundles to install
        final List<IPluginModelBase> workspaceModels = getWorkspaceModelDependencies(model);

        // Check whether or not such workspace models have extension points
        final List<String> registryContributors = new UniqueEList<String>();
        for (IPluginModelBase workspaceModel : workspaceModels) {
            if (workspaceModel.getPluginBase().getExtensions() != null && workspaceModel.getPluginBase().getExtensions().length > 0) {
                String workspaceBundleId = BundleHelper.getBundleId(workspaceModel);
                final String location = getLocation(workspaceModel);
                if (workspaceBundleId != null && !projectBundles.containsKey(location)) {
                    registryContributors.add(workspaceBundleId);
                }
            }
        }

        final ObjectHolder<Boolean> loadCompleted = new ObjectHolder<Boolean>();

        // build a listener to wait for asynchronous extensions notifications
        IRegistryEventListener registryListener = null;
        if (!registryContributors.isEmpty()) {

            registryListener = new IRegistryEventListener() {

                public void removed(IExtension[] extensions) {
                    // Nothing to do
                }

                public void added(IExtension[] extensions) {
                    // Process
                    for (IExtension extension : extensions) {
                        registryContributors.remove(extension.getContributor().getName());
                        if (registryContributors.isEmpty()) {
                            loadCompleted.object = Boolean.TRUE;
                        }
                    }
                }

                public void added(IExtensionPoint[] extensionPoints) {
                    // Nothing to do
                }

                public void removed(IExtensionPoint[] extensionPoints) {
                    // Nothing to do
                }

            };

            // Register
            RegistryFactory.getRegistry().addListener(registryListener);

        }

        // Install workspace bundles
        final List<Bundle> bundles = new UniqueEList<Bundle>();
        internalInstallBundle(bundles, workspaceModels);

        // Wait for extensions notifications if applicable
        if (registryListener != null) {
            int timeout = 20;
            try {
                while (loadCompleted.object == null && timeout-- > 0)
                    Thread.sleep(100);
            } catch (InterruptedException e) {

            } finally {
                // Unregister
                RegistryFactory.getRegistry().removeListener(registryListener);
            }
            if (timeout < 0)
                EGFCorePlugin.getDefault().logWarning("Some bundles (related to " + bundleId + ") may not be fully loaded.");
        }

        // Trace
        if (EGFCoreDebug.isDebugBundleSession()) {
            for (Bundle bundle : bundles) {
                EGFCorePlugin.getDefault().logInfo(NLS.bind("Workspace Bundle ''{0}'' is started.", bundle.getSymbolicName())); //$NON-NLS-1$
            }
        }

        // Return our new bundle
        return Platform.getBundle(bundleId);

    }

    private void internalInstallBundle(List<Bundle> bundles, List<IPluginModelBase> workspaceModels) throws CoreException {

        // Uninstall runtime bundles if any
        uninstallRuntimeBundle(workspaceModels);
        // Install workspace bundles
        final List<Bundle> workspaceBundles = new ArrayList<Bundle>(bundles);
        installWorkspaceModels(bundles, workspaceModels);
        // Refresh installed workspace bundles if any
        if (!bundles.isEmpty()) {
            refreshPackages(bundles.toArray(new Bundle[bundles.size()]));
        }
        // Start them
        for (Bundle bundle : bundles) {
            try {
                if (bundle.getState() != Bundle.ACTIVE) {
                    bundle.start(Bundle.START_TRANSIENT);
                } else {
                    workspaceBundles.remove(bundle);
                }
            } catch (Throwable t) {
                throw new CoreException(EGFCorePlugin.getDefault().newStatus(IStatus.ERROR, NLS.bind(EGFCoreMessages.ProjectBundleSession_StartFailure, bundle), t));
            }
        }

    }

    private void uninstallRuntimeBundle(List<IPluginModelBase> workspaceModels) throws CoreException {

        if (workspaceModels == null || workspaceModels.isEmpty()) {
            return;
        }
        List<IPluginModelBase> models = new UniqueEList<IPluginModelBase>();

        // Uninstall Runtime Bundle
        List<Bundle> bundles = new UniqueEList<Bundle>();
        for (IPluginModelBase workspaceModel : workspaceModels) {

            // Ignore already uninstalled bundle
            if (projectBundles.get(getLocation(workspaceModel)) != null) {
                continue;
            }

            // Uninstall Runtime if any
            String bundleId = BundleHelper.getBundleId(workspaceModel);
            if (bundleId == null) {
                continue;
            }
            Bundle bundle = Platform.getBundle(bundleId);
            if (bundle == null) {
                continue;
            }
            if (bundle.getState() == Bundle.INSTALLED || bundle.getState() == Bundle.RESOLVED || bundle.getState() == Bundle.STARTING || bundle.getState() == Bundle.STOPPING || bundle.getState() == Bundle.ACTIVE) {
                uninstallBundle(bundle);
            }

            // Store
            models.add(workspaceModel);
            uninstalled.add(bundle.getLocation());
            bundles.add(bundle);

            // Trace
            if (EGFCoreDebug.isDebugBundleSession()) {
                if (uninstalled.size() == 0) {
                    EGFCorePlugin.getDefault().logInfo("Start ProjectBundleSession..."); //$NON-NLS-1$
                }
            }

        }

        // Refresh uninstalled runtime bundles if any
        if (models.isEmpty() == false) {
            refreshPackages(bundles.toArray(new Bundle[bundles.size()]));
            if (EGFCoreDebug.isDebugBundleSession()) {
                for (IPluginModelBase model : models) {
                    EGFCorePlugin.getDefault().logInfo(NLS.bind("Runtime Bundle ''{0}'' is uninstalled.", BundleHelper.getBundleId(model))); //$NON-NLS-1$
                }
            }
        }

        return;

    }

    private List<IPluginModelBase> getWorkspaceModelDependencies(IPluginModelBase base) throws CoreException {
        List<IPluginModelBase> dependencies = new UniqueEList<IPluginModelBase>();
        // Store base
        dependencies.add(base);
        // Analyse base
        BundleDescription description = base.getBundleDescription();
        if (description == null) {
            return dependencies;
        }
        for (BundleSpecification requiredBundle : description.getRequiredBundles()) {
            for (IPluginModelBase workspaceModel : PluginRegistry.getWorkspaceModels()) {
                if (requiredBundle.isSatisfiedBy(workspaceModel.getBundleDescription())) {
                    dependencies.addAll(getWorkspaceModelDependencies(workspaceModel));
                    break;
                }
            }
        }
        for (ImportPackageSpecification importPackage : description.getImportPackages()) {
            for (IPluginModelBase workspaceModel : PluginRegistry.getWorkspaceModels()) {
                for (ExportPackageDescription export : workspaceModel.getBundleDescription().getExportPackages()) {
                    if (importPackage.isSatisfiedBy(export)) {
                        dependencies.addAll(getWorkspaceModelDependencies(workspaceModel));
                        break;
                    }
                }
            }
        }
        if (isRuntimeBundlePriority()) {
            for (IPluginModelBase innerBase : new ArrayList<IPluginModelBase>(dependencies)) {
                if (Platform.getBundle(innerBase.getBundleDescription().getSymbolicName()) != null) {
                    dependencies.remove(innerBase);
                }
            }
        }
        return dependencies;
    }

    /**
     * Installs the bundle corresponding to the given location. This will fail
     * if
     * the location doesn't point
     * to a valid bundle.
     * 
     * @param location
     *            Location of the bundle to be installed.
     * @return The installed bundle.
     * @throws BundleException
     *             Thrown if the Bundle isn't valid.
     * @throws IllegalStateException
     *             Thrown if the bundle couldn't be installed properly.
     */
    private Bundle installBundle(String location) throws CoreException {
        Bundle bundle = null;
        try {
            bundle = context.installBundle(location);
        } catch (Throwable t) {
            throw new CoreException(EGFCorePlugin.getDefault().newStatus(IStatus.ERROR, NLS.bind(EGFCoreMessages.ProjectBundleSession_InstallationFailure, location), t));
        }
        // Not sure if it's needed, anyway we are conservative on that one
        if (bundle == null) {
            throw new CoreException(EGFCorePlugin.getDefault().newStatus(IStatus.ERROR, NLS.bind(EGFCoreMessages.ProjectBundleSession_InstallationFailure, location), null));
        }
        int state = bundle.getState();
        if (state != Bundle.INSTALLED) {
            throw new CoreException(EGFCorePlugin.getDefault().newStatus(IStatus.ERROR, NLS.bind(EGFCoreMessages.ProjectBundleSession_IllegalBundleState, bundle, state), null));
        }
        return bundle;
    }

    /**
     * This will set the equinox classpath of <code>bundle</code> to reflect the
     * eclipse classpath of <code>plugin</code>.
     * 
     * @param project
     *            The eclipse plugin which classpath is to be set for its
     *            corresponding equinox bundle.
     * @param bundle
     *            The equinox bundle which classpath is to reflect an eclipse
     *            development plugin.
     */
    private void addOutputFoldersToBundleClasspath(IProject project, Bundle bundle) throws CoreException {
        List<String> outputFolders = JavaHelper.getStringOutputFolders(JavaCore.create(project));
        BaseData bundleData = (BaseData) ((AbstractBundle) bundle).getBundleData();
        StringBuilder classpath = new StringBuilder();
        if (outputFolders.size() == 0) {
            classpath.append("."); //$NON-NLS-1$
        } else {
            for (Iterator<String> it = outputFolders.iterator(); it.hasNext();) {
                if (classpath.length() > 0) {
                    classpath.append(","); //$NON-NLS-1$ 
                }
                classpath.append(it.next());
            }
        }
        bundleData.setClassPathString(classpath.toString());
    }

    /**
     * Returns the bundle corresponding to the IProject if any.
     * 
     * @param id
     *            The plug-in ID of the bundle we seek.
     * @return The bundle corresponding to the given location if any,
     *         <code>null</code> otherwise.
     */
    public Bundle getBundle(String id) throws CoreException {
        if (id == null || id.trim().length() == 0) {
            return null;
        }
        IPluginModelBase model = PluginRegistry.findModel(id.trim());
        if (model == null) {
            return null;
        }
        // Check if we face a non workspace model
        if (model.getUnderlyingResource() == null || isRuntimeBundlePriority()) {
            return Platform.getBundle(id.trim());
        }
        String location = getLocation(model);
        if (location == null) {
            return null;
        }
        // Workspace model
        Bundle bundle = projectBundles.get(location);
        if (bundle == null) {
            return installBundle(model);
        }
        return bundle;
    }

    /**
     * Returns the bundle corresponding to the IProject if any.
     * 
     * @param project
     *            The IProject of the bundle we seek.
     * @return The bundle corresponding to the given location if any,
     *         <code>null</code> otherwise.
     */
    public Bundle getBundle(IProject project) throws CoreException {
        if (project == null) {
            return null;
        }
        IPluginModelBase model = PluginRegistry.findModel(project);
        if (model == null) {
            return null;
        }
        if (isRuntimeBundlePriority()) {
            String id = BundleHelper.getBundleId(model);
            if (id != null) {
                Bundle bundle = Platform.getBundle(id);
                if (bundle != null) {
                    return bundle;
                }
            }
        }
        String location = getLocation(model);
        if (location == null) {
            return null;
        }
        Bundle bundle = projectBundles.get(location);
        if (bundle == null) {
            bundle = installBundle(model);
        }
        return bundle;
    }

    /**
     * Refreshes all exported packages of the given bundles. This must be called
     * after installing the bundle.
     * 
     * @param bundles
     *            Bundles which exported packages are to be refreshed.
     */
    private void refreshPackages(Bundle[] bundles) throws CoreException {

        ServiceReference packageAdminReference = context.getServiceReference(PackageAdmin.class.getName());
        PackageAdmin packageAdmin = null;
        if (packageAdminReference != null) {
            packageAdmin = (PackageAdmin) context.getService(packageAdminReference);
        }

        if (packageAdmin == null) {
            return;
        }

        // State for thread synchronization
        final boolean[] framework = new boolean[] { false };
        // Storage for thread framework exception
        final Throwable[] throwable = new Throwable[1];

        // Listener
        FrameworkListener listener = new FrameworkListener() {

            public void frameworkEvent(FrameworkEvent event) {
                if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED || event.getType() == FrameworkEvent.ERROR) {
                    if (event.getType() == FrameworkEvent.ERROR) {
                        throwable[0] = event.getThrowable();
                    }
                    synchronized (framework) {
                        framework[0] = true;
                        framework.notifyAll();
                    }
                } else if (event.getType() == FrameworkEvent.WARNING) {
                    if (event.getThrowable() != null) {
                        EGFCorePlugin.getDefault().logWarning(event.getThrowable());
                    }
                }
            }

        };
        context.addFrameworkListener(listener);

        // Refresh packages
        packageAdmin.refreshPackages(bundles);
        synchronized (framework) {
            while (framework[0] == false) {
                try {
                    framework.wait();
                } catch (InterruptedException e) {
                    break;
                }
            }
        }
        context.removeFrameworkListener(listener);
        context.ungetService(packageAdminReference);

        // Throw a CoreException
        if (throwable[0] != null) {
            throw new CoreException(EGFCorePlugin.getDefault().newStatus(IStatus.ERROR, EGFCoreMessages.ProjectBundleSession_PackageRefreshFailure, throwable[0]));
        }

    }

    /**
     * This can be used to uninstall all manually loaded bundles from the
     * registry
     * and remove all listeners.
     * It will be called on plugin stopping and is not intended to be called by
     * clients.
     * 
     * @noreference This method is not intended to be referenced by clients.
     */
    public void dispose() throws CoreException {

        // shallow copy our bundle collector
        final List<Bundle> uninstalledBundles = new UniqueEList<Bundle>(uninstalled.size());

        // Uninstall workspace bundle
        if (projectBundles.isEmpty() == false || uninstalled.isEmpty() == false) {

            // Trace
            if (EGFCoreDebug.isDebugBundleSession()) {
                if (projectBundles.isEmpty() == false || uninstalled.isEmpty() == false) {
                    EGFCorePlugin.getDefault().logInfo("Dispose ProjectBundleSession..."); //$NON-NLS-1$        
                }
            }

            // Uninstall workspace bundle
            if (projectBundles.isEmpty() == false) {
                for (Bundle bundle : projectBundles.values()) {
                    uninstallBundle(bundle);
                }
                // Refresh Packages
                refreshPackages(projectBundles.values().toArray(new Bundle[projectBundles.size()]));
                // Tracing
                if (EGFCoreDebug.isDebugBundleSession()) {
                    if (projectBundles.isEmpty() == false) {
                        for (Bundle bundle : projectBundles.values()) {
                            EGFCorePlugin.getDefault().logInfo(NLS.bind("Workspace Bundle ''{0}'' is uninstalled.", bundle.getSymbolicName()), 1); //$NON-NLS-1$
                        }
                    }
                }
            }

            // Install runtime bundle
            if (uninstalled.isEmpty() == false) {
                for (String location : uninstalled) {
                    uninstalledBundles.add(installBundle(location));
                }
                // Refresh Packages
                refreshPackages(uninstalledBundles.toArray(new Bundle[uninstalledBundles.size()]));
                // Tracing
                if (EGFCoreDebug.isDebugBundleSession()) {
                    if (uninstalled.isEmpty() == false) {
                        for (Bundle bundle : uninstalledBundles) {
                            EGFCorePlugin.getDefault().logInfo(NLS.bind("Runtime Bundle ''{0}'' is installed.", bundle.getSymbolicName()), 1); //$NON-NLS-1$
                        }
                    }
                }
            }

        }

        // Final
        projectBundles.clear();
        uninstalled.clear();

    }

    /**
     * Uninstall the given bundle from the context.
     * 
     * @param bundle
     *            The bundle that is to be uninstalled.
     * @throws CoreException
     *             Thrown if a lifecycle issue arises.
     */
    private void uninstallBundle(Bundle bundle) throws CoreException {
        try {
            bundle.uninstall();
        } catch (BundleException be) {
            throw new CoreException(EGFCorePlugin.getDefault().newStatus(IStatus.ERROR, NLS.bind(EGFCoreMessages.ProjectBundleSession_UninstallationFailure, bundle.getSymbolicName()), be));
        }
    }

    // TODO: not sure if we still need this support while we have now runtime
    // and target platform support
    private boolean isRuntimeBundlePriority() {
        if (runtimeBundlePriority == null) {
            String property = System.getProperty(EGF_TARGET_BUNDLE_PRIORITY);
            runtimeBundlePriority = Boolean.TRUE.toString().equals(property);
        }
        return runtimeBundlePriority;
    }

}
