/*
 * Copyright (c) 2002-2003 IST-2004-2006-511731 ModelWare - ModelBus.
 * All rights reserved.
 *
 * This software is published under the terms of the ModelBus Software License
 * 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.
 * A copy of ModelBus Software License is provided with this distribution in
 * doc/LICENSE.txt file.
 */

/*
 * Created on 17 juin 2005
 *
 */
package org.eclipse.mddi.modelbus.adapter.infrastructure.notification;

import java.util.Collection;
import java.util.StringTokenizer;
import java.util.Vector;

import org.eclipse.mddi.modelbus.adapter.user.notification.Notification;
import org.eclipse.mddi.modelbus.adapter.user.notification.NotificationConsumer;
import org.eclipse.mddi.modelbus.adapter.user.notification.NotificationPublisher;


/**
 * NotificationServiceClient provides the communication between Adapter and NotificationService.
 * The Adapter can use NotificationServiceClient to subscribe/unsubscribe Tools to a NotificationService.
 * The Adapter can also use it to emit to notifications to NotificationService 
 * 
 * @author Prawee Sriplakich (LIP6)
 *
 *
 */
public class NotifServiceClient implements NotificationPublisher {

    String notifServiceLocation;
    
    /**
     * @param location
     */
    public NotifServiceClient(String _location) {
        this.notifServiceLocation = _location;
    }
    

    
    /**
     * Informs the notification service that 
     * the consumer <code>con</code> does not want to receive notifications 
     * anymore
     * 
     * @param port the port used for receiving notifications
     * @param con Consumer
     * @param topics Topics of the notifications that the consumer wants. It is a comma-sperated list.
     * @throws NotifServiceNotAvailableException
     * 
     */
    public void subscribeConsumer(int port, NotificationConsumer con, String topics) throws NotifServiceNotAvailableException{
       NotifDelegate notifDelegate = NotifServiceManager.getInstance().getNotifDelegate();
        try {
            String consumerUrl;
            consumerUrl = notifDelegate.bindConsumerToServer(port, con);
            String[] topicArray = getTopicArray(topics);

            NotificationServiceUtil.subscribe(notifServiceLocation, consumerUrl, topicArray);
       }catch (NotifServiceNotAvailableException ne){
            throw ne;
        }catch (Exception e) {
            e.printStackTrace();
        }
       
    }
    
    /**
     * 
     * Converts a comma-seperated list to a string array.
     * 
     * @param topics
     * 
     */
    public static String[] getTopicArray(String topics) {
        StringTokenizer tokenizer = new StringTokenizer(topics, ",");
        Collection c = new Vector();
        while(tokenizer.hasMoreTokens()) {
          String topic = tokenizer.nextToken();    
          c.add(topic);
        }
        String[] topicArray = new String[c.size()];
        topicArray = (String[]) c.toArray(topicArray);        
        return topicArray;
    }
    
    
    /**
     * Informs the notification service that 
     * the consumer <code>con</code> wants to receive notifications 
     * that will be produced in the future
     * 
     * @param con consumer
     * 
     */
    public void unsubscribeConsumer(NotificationConsumer con) {
        NotifDelegate notifDelegate = NotifServiceManager.getInstance().getNotifDelegate();
        notifDelegate.unbindConsumerToServer(con);
        
        //TODO
        NotificationServiceUtil.unsubscribe();
    }
    
    
    /**
     * Emits a notificationto NotificationService
     *
     */    
    public void publish(Notification notif) {
        //serialize notification
        SerializedNotification serialized = new SerializedNotification(notif);
        
        NotificationServiceUtil.publish(notifServiceLocation, serialized.topic, serialized.message);
    }
    
    
    
    /**
     * Tests the availability 
     * 
     * @return
     */
    public boolean isAvailable() {
      return true;    
    }
    
   

}
