/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.felix.eventadmin.impl.adapter;

import java.util.Dictionary;
import java.util.Hashtable;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.FrameworkListener;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.event.EventConstants;

/**
 * This class registers itself as a listener for framework events and posts them via
 * the EventAdmin as specified in 113.6.3 OSGi R4 compendium.
 *
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class FrameworkEventAdapter extends AbstractAdapter implements FrameworkListener
{
    /**
     * The constructor of the adapter. This will register the adapter with the
     * given context as a <tt>FrameworkListener</tt> and subsequently, will
     * post received events via the given EventAdmin.
     *
     * @param context The bundle context with which to register as a listener.
     * @param admin The <tt>EventAdmin</tt> to use for posting events.
     */
    public FrameworkEventAdapter(final BundleContext context, final EventAdmin admin)
    {
        super(admin);

        context.addFrameworkListener(this);
    }

    @Override
    public void destroy(BundleContext context) {
        context.removeFrameworkListener(this);
    }

    /**
     * Once a framework event is received this method assembles and posts an event
     * via the <tt>EventAdmin</tt> as specified in 113.6.3 OSGi R4 compendium.
     *
     * @param event The event to adapt.
     */
    @Override
    public void frameworkEvent(final FrameworkEvent event)
    {
        final Dictionary<String, Object> properties = new Hashtable<>();

        properties.put(EventConstants.EVENT, event);

        final Bundle bundle = event.getBundle();

        if (null != bundle)
        {
            properties.put("bundle.id", bundle.getBundleId());

            final String symbolicName = bundle.getSymbolicName();

            if (null != symbolicName)
            {
                properties.put(EventConstants.BUNDLE_SYMBOLICNAME,
                    symbolicName);
            }

            properties.put("bundle", bundle);
        }

        final Throwable thrown = event.getThrowable();

        if (null != thrown)
        {
            properties.put(EventConstants.EXCEPTION_CLASS,
                thrown.getClass().getName());

            final String message = thrown.getMessage();

            if (null != message)
            {
                properties.put(EventConstants.EXCEPTION_MESSAGE,
                    message);
            }

            properties.put(EventConstants.EXCEPTION, thrown);
        }

        final StringBuilder topic = new StringBuilder(
            FrameworkEvent.class.getName().replace('.', '/'))
            .append('/');

        switch (event.getType())
        {
            case FrameworkEvent.STARTED:
                topic.append("STARTED");
                break;
            case FrameworkEvent.ERROR:
                topic.append("ERROR");
                break;
            case FrameworkEvent.PACKAGES_REFRESHED:
                topic.append("PACKAGES_REFRESHED");
                break;
            case FrameworkEvent.STARTLEVEL_CHANGED:
                topic.append("STARTLEVEL_CHANGED");
                break;
            case FrameworkEvent.WARNING:
                topic.append("WARNING");
                break;
            case FrameworkEvent.INFO:
                topic.append("INFO");
                break;
            default:
                return; // IGNORE EVENT
        }

        try {
            getEventAdmin().postEvent(new Event(topic.toString(), properties));
        } catch(IllegalStateException e) {
            // This is o.k. - indicates that we are stopped.
        }
    }
}
