/*******************************************************************************
 * Copyright (c) 2006, 2014 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:
 *   David Knibb               initial implementation
 *   Matthew Webster           Eclipse 3.2 changes
 *   Martin Lippert            supplementing mechanism reworked
 *******************************************************************************/

package org.eclipse.equinox.weaving.hooks;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.equinox.service.weaving.ISupplementerRegistry;
import org.eclipse.equinox.weaving.adaptors.Debug;
import org.eclipse.equinox.weaving.adaptors.IWeavingAdaptor;
import org.eclipse.equinox.weaving.adaptors.WeavingAdaptor;
import org.eclipse.equinox.weaving.adaptors.WeavingAdaptorFactory;
import org.eclipse.osgi.internal.loader.ModuleClassLoader;
import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
import org.eclipse.osgi.internal.loader.classpath.ClasspathManager;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.PackageAdmin;

public class WeavingHook extends AbstractWeavingHook {

    private final WeavingAdaptorFactory adaptorFactory;

    private final Map<Long, IWeavingAdaptor> adaptors;

    private BundleContext bundleContext;

    public WeavingHook() {
        if (Debug.DEBUG_GENERAL) Debug.println("- WeavingHook.<init>()");

        this.adaptorFactory = new WeavingAdaptorFactory();
        this.adaptors = new HashMap<Long, IWeavingAdaptor>();
    }

    @Override
    public void classLoaderCreated(final ModuleClassLoader classLoader) {
        if (Debug.DEBUG_GENERAL)
            Debug.println("> WeavingHook.initializedClassLoader() bundle="
                    + classLoader.getBundle().getSymbolicName()
                    + ", loader="
                    + classLoader
                    + ", bundleFile="
                    + classLoader.getClasspathManager().getGeneration()
                            .getBundleFile());

        final IWeavingAdaptor adaptor = createWeavingAdaptor(classLoader
                .getClasspathManager().getGeneration(), classLoader);
        this.adaptors.put(classLoader.getBundle().getBundleId(), adaptor);

        if (Debug.DEBUG_GENERAL)
            Debug.println("< WeavingHook.initializedClassLoader() adaptor="
                    + adaptor);
    }

    private IWeavingAdaptor createWeavingAdaptor(final Generation generation,
            final ModuleClassLoader classLoader) {
        if (Debug.DEBUG_GENERAL)
            Debug.println("> WeavingHook.createAspectJAdaptor() location="
                    + generation.getRevision().getRevisions().getModule()
                            .getLocation());
        IWeavingAdaptor adaptor = null;

        if (adaptorFactory != null) {
            adaptor = new WeavingAdaptor(generation, adaptorFactory, null,
                    null, classLoader);
        } else {
            if (Debug.DEBUG_GENERAL)
                Debug.println("- WeavingHook.createAspectJAdaptor() factory="
                        + adaptorFactory);
        }

        if (Debug.DEBUG_GENERAL)
            Debug.println("< WeavingHook.createAspectJAdaptor() adaptor="
                    + adaptor);
        return adaptor;
    }

    public IWeavingAdaptor getAdaptor(final long bundleID) {
        return this.adaptors.get(bundleID);
    }

    public IWeavingAdaptor getHostBundleAdaptor(final long bundleID) {
        final Bundle bundle = this.bundleContext.getBundle(bundleID);
        if (bundle != null) {
            final Bundle host = adaptorFactory.getHost(bundle);
            if (host != null) {
                final long hostBundleID = host.getBundleId();
                return this.adaptors.get(hostBundleID);
            }
        }
        return null;
    }

    private void initialize(final BundleContext context) {
        if (Debug.DEBUG_GENERAL)
            Debug.println("> WeavingHook.initialize() context=" + context);

        this.bundleContext = context;

        final ISupplementerRegistry supplementerRegistry = getSupplementerRegistry();
        adaptorFactory.initialize(context, supplementerRegistry);

        final ServiceReference<PackageAdmin> serviceReference = context
                .getServiceReference(PackageAdmin.class);
        final PackageAdmin packageAdmin = context.getService(serviceReference);

        supplementerRegistry.setBundleContext(context);
        supplementerRegistry.setPackageAdmin(packageAdmin);
        context.addBundleListener(new SupplementBundleListener(
                supplementerRegistry));

        // re-build supplementer registry state for installed bundles
        final Bundle[] installedBundles = context.getBundles();
        for (int i = 0; i < installedBundles.length; i++) {
            if (installedBundles[i].getState() != Bundle.UNINSTALLED) {
                supplementerRegistry
                        .addSupplementer(installedBundles[i], false);
            }
        }
        for (int i = 0; i < installedBundles.length; i++) {
            if (installedBundles[i].getState() != Bundle.UNINSTALLED) {
                supplementerRegistry.addSupplementedBundle(installedBundles[i]);
            }
        }

        if (Debug.DEBUG_GENERAL)
            Debug.println("< WeavingHook.initialize() adaptorFactory="
                    + adaptorFactory);
    }

    /**
     * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#processClass(java.lang.String,
     *      byte[], org.eclipse.osgi.baseadaptor.loader.ClasspathEntry,
     *      org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry,
     *      org.eclipse.osgi.baseadaptor.loader.ClasspathManager)
     */
    @Override
    public byte[] processClass(final String name, final byte[] classbytes,
            final ClasspathEntry classpathEntry, final BundleEntry entry,
            final ClasspathManager manager) {
        byte[] newClassytes = null;
        if (entry instanceof WeavingBundleEntry) {
            final WeavingBundleEntry ajBundleEntry = (WeavingBundleEntry) entry;
            if (!ajBundleEntry.dontWeave()) {
                final IWeavingAdaptor adaptor = ajBundleEntry.getAdaptor();
                newClassytes = adaptor.weaveClass(name, classbytes);
            }
        }
        return newClassytes;
    }

    /**
     * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#recordClassDefine(java.lang.String,
     *      java.lang.Class, byte[],
     *      org.eclipse.osgi.baseadaptor.loader.ClasspathEntry,
     *      org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry,
     *      org.eclipse.osgi.baseadaptor.loader.ClasspathManager)
     */
    @Override
    public void recordClassDefine(final String name, final Class<?> clazz,
            final byte[] classbytes, final ClasspathEntry classpathEntry,
            final BundleEntry entry, final ClasspathManager manager) {
        if (clazz == null) {
            if (Debug.DEBUG_GENERAL) {
                Debug.println("Error in defining class: " + name); //$NON-NLS-1$
            }
            return;
        }
        if (entry instanceof WeavingBundleEntry) {
            final WeavingBundleEntry ajBundleEntry = (WeavingBundleEntry) entry;
            if (!ajBundleEntry.dontWeave()) {
                final IWeavingAdaptor adaptor = ajBundleEntry.getAdaptor();
                final URL sourceFileURL = ajBundleEntry.getBundleFileURL();
                adaptor.storeClass(name, sourceFileURL, clazz, classbytes);
            }
        }
    }

    public void resetAdaptor(final long bundleID) {
        this.adaptors.remove(bundleID);
    }

    /**
     * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#frameworkStart(org.osgi.framework.BundleContext)
     */
    public void start(final BundleContext context) throws BundleException {
        initialize(context);
    }

    /**
     * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#frameworkStop(org.osgi.framework.BundleContext)
     */
    public void stop(final BundleContext context) throws BundleException {
        adaptorFactory.dispose(context);
    }

    /**
     * @see org.eclipse.osgi.internal.hookregistry.BundleFileWrapperFactoryHook#wrapBundleFile(org.eclipse.osgi.storage.bundlefile.BundleFile,
     *      org.eclipse.osgi.storage.BundleInfo.Generation, boolean)
     */
    public BundleFileWrapper wrapBundleFile(final BundleFile bundleFile,
            final Generation generation, final boolean base) {
        BundleFileWrapper wrapped = null;
        if (Debug.DEBUG_BUNDLE)
            Debug.println("> WeavingHook.wrapBundleFile() bundle="
                    + (generation.getRevision() != null ? generation
                            .getRevision().getSymbolicName() : generation
                            .getBundleInfo().getBundleId()) + " bundleFile="
                    + bundleFile + ", generation=" + generation + ", base="
                    + base + ", baseFile=" + bundleFile.getBaseFile());

        if (base) {
            wrapped = new BaseWeavingBundleFile(new BundleAdaptorProvider(
                    generation, this), bundleFile);
        } else {
            wrapped = new WeavingBundleFile(new BundleAdaptorProvider(
                    generation, this), bundleFile);
        }
        if (Debug.DEBUG_BUNDLE)
            Debug.println("< WeavingHook.wrapBundleFile() wrapped=" + wrapped);
        return wrapped;
    }

}
