/* 
-*- coding: latin-1 -*-

This file is part of RefactorErl.

RefactorErl is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

RefactorErl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with RefactorErl.  If not, see <http://plc.inf.elte.hu/erlang/>.

The Original Code is RefactorErl.

The Initial Developer of the Original Code is Eötvös Loránd University.
Portions created  by Eötvös Loránd University and ELTE-Soft Ltd.
are Copyright 2007-2025 Eötvös Loránd University, ELTE-Soft Ltd.
and Ericsson Hungary. All Rights Reserved.
*/

package com.refactorerl.ui.presentation.event;

import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;

import com.refactorerl.ui.communication.event.IEvent;
import com.refactorerl.ui.communication.event.IEventDispatcher;
import com.refactorerl.ui.communication.event.IEventHandler;
import com.refactorerl.ui.presentation.Activator;

/**
 * Wrapper for an OSGi EventAdmin instance. Can be used to subscribe handlers for
 * certain events and to fire these or some other events.
 * 
 * @author Daniel Lukacs, 2014 ELTE IK
 *
 */
public class ReferlEventDispatcher implements IEventDispatcher {

	static private String getDefaultPropertyName() {
		return ""; //$NON-NLS-1$
	}

	public Object getValue(IEvent event) {
		return event
				.getProperty(ReferlEventDispatcher.getDefaultPropertyName());
	}

	private Map<IEventHandler, ServiceRegistration> registrations = new HashMap<>();

	public ReferlEventDispatcher() {
	}

	private EventAdmin eventAdmin = null;

	public void subscribe(String topic, IEventHandler handler) {

		ReferlEventHandler reh = new ReferlEventHandler(handler);

		BundleContext ctx = FrameworkUtil.getBundle(Activator.class)
				.getBundleContext();
		Dictionary<String, String> props = new Hashtable<String, String>();
		props.put(EventConstants.EVENT_TOPIC, topic);
		ServiceRegistration reg = ctx.registerService(
				EventHandler.class.getName(), reh, props);

		registrations.put(reh, reg);
	}

	public void unsubscribe(IEventHandler handler) {
		ServiceRegistration reg = registrations.remove(new ReferlEventHandler(handler)); // equals will make this happen
		if (reg != null)
			reg.unregister();
	}

	public void fire(String topic, Object msg) {
		Map<String, Object> properties = new HashMap<String, Object>();
		properties.put(getDefaultPropertyName(), msg);

		Event event = new Event(topic, properties);

		eventAdmin.sendEvent(event); // used for blocking

		// eventAdmin.postEvent(event); // used for non-blocking

	}

	public void start() {
		BundleContext context = FrameworkUtil.getBundle(Activator.class)
				.getBundleContext();

		ServiceReference<EventAdmin> ref = context
				.getServiceReference(EventAdmin.class);
		eventAdmin = context.getService(ref);

		if (eventAdmin == null) {
			System.out.println("HIBA eventamdin"); //$NON-NLS-1$
			return;
		}

	}

	public void stop() {

		BundleContext context = FrameworkUtil.getBundle(Activator.class)
				.getBundleContext();
		ServiceReference<EventAdmin> ref = context
				.getServiceReference(EventAdmin.class);
		context.ungetService(ref);
	}

}
