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

package org.eclipse.equinox.weaving.hooks;

import java.io.IOException;
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.baseadaptor.BaseData;
import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry;
import org.eclipse.osgi.baseadaptor.loader.ClasspathManager;
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("- AspectJHook.<init>()");
        this.adaptorFactory = new WeavingAdaptorFactory();
        this.adaptors = new HashMap<Long, IWeavingAdaptor>();
    }

    /**
     * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#frameworkStart(org.osgi.framework.BundleContext)
     */
    @Override
    public void frameworkStart(final BundleContext context)
            throws BundleException {
        //		Debug.println("? AspectJHook.frameworkStart() context=" + context + ", fdo=" + FrameworkDebugOptions.getDefault());
        initialize(context);
    }

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

    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;
    }

    /**
     * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#initializedClassLoader(org.eclipse.osgi.baseadaptor.loader.BaseClassLoader,
     *      org.eclipse.osgi.baseadaptor.BaseData)
     */
    @Override
    public void initializedClassLoader(final BaseClassLoader baseClassLoader,
            final BaseData data) {
        if (Debug.DEBUG_GENERAL)
            Debug
                    .println("> AspectJHook.initializedClassLoader() bundle="
                            + data.getSymbolicName() + ", loader="
                            + baseClassLoader + ", data=" + data
                            + ", bundleFile=" + data.getBundleFile());

        final IWeavingAdaptor adaptor = createAspectJAdaptor(data);
        adaptor.setBaseClassLoader(baseClassLoader);
        adaptor.initialize();
        this.adaptors.put(data.getBundleID(), adaptor);

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

    /**
     * @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 (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);
    }

    @Override
    public BundleFile wrapBundleFile(final BundleFile bundleFile,
            final Object content, final BaseData data, final boolean base)
            throws IOException {
        BundleFile wrapped = null;
        if (Debug.DEBUG_BUNDLE)
            Debug
                    .println("> AspectJBundleFileWrapperFactoryHook.wrapBundleFile() bundle="
                            + data.getSymbolicName()
                            + " bundleFile="
                            + bundleFile
                            + ", content="
                            + content
                            + ", data="
                            + data
                            + ", base="
                            + base
                            + ", baseFile="
                            + bundleFile.getBaseFile());

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

    private IWeavingAdaptor createAspectJAdaptor(final BaseData baseData) {
        if (Debug.DEBUG_GENERAL)
            Debug.println("> AspectJHook.createAspectJAdaptor() location="
                    + baseData.getLocation());
        IWeavingAdaptor adaptor = null;

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

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

    private IWeavingAdaptor getAspectJAdaptor(final BaseData data) {
        return getAdaptor(data.getBundleID());
    }

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

        this.bundleContext = context;

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

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

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

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

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

}
