/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.kiwi.cometd.client;

import cz.kiwi.cometd.listener.MetaChannelListener;
import cz.kiwi.cometd.utils.CometdClientUtils;
import cz.kiwi.cometd.utils.ConfigResourceBundle;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.client.ClientSession;
import org.cometd.bayeux.client.ClientSessionChannel;
import org.cometd.client.ext.AckExtension;
import org.cometd.client.ext.TimestampClientExtension;
import org.cometd.client.transport.ClientTransport;
import org.cometd.client.transport.LongPollingTransport;
import org.eclipse.jetty.client.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author esner
 */
public class CometdKiwiClient {
    
    final static Logger logger = LoggerFactory.getLogger(CometdKiwiClient.class);
   
    ClientSession clientSession;
    ClientSessionChannel.MessageListener metaChannelListener;
    
    public CometdKiwiClient() {
        
    }
    
    public boolean connect() throws IOException {
        ClientTransport transport = getClientTransport();
        
        if (transport == null)
            return false;
        
        clientSession = new BayeuxKiwiClient(ConfigResourceBundle.getInstance().getObject("url") + ConfigResourceBundle.getInstance().getObject("serviceName"), transport);
        
        if (clientSession == null)
            return false;
        
        metaChannelListener = new MetaChannelListener();
        
        clientSession.getChannel(Channel.META_HANDSHAKE).addListener(metaChannelListener);
        clientSession.addExtension(new AckExtension());
        clientSession.addExtension(new TimestampClientExtension());
 
        Map<String, Object> ext = new HashMap<String, Object>();
        Map<String, Object> auth = new HashMap<String, Object>();
        Map<String, Object> values = new HashMap<String, Object>();
        
        values.put("id", ConfigResourceBundle.getInstance().getObject("deviceID"));
        values.put("accessCode", ConfigResourceBundle.getInstance().getObject("accessCode"));
        
        auth.put("authentication", values);
        ext.put("ext", auth);
        
        clientSession.handshake(ext);
        
        return true;
    }
    
    public void disconnect() {
        if (clientSession == null)
            return;
        
        if (metaChannelListener != null)
            clientSession.getChannel(Channel.META_HANDSHAKE).unsubscribe(metaChannelListener);
        
        logger.info("Cometd client disconnect");
        clientSession.disconnect();
    }

    public void publish(String channel, String content) {
        if (clientSession == null)
            return;
        
        clientSession.getChannel(channel).publish(content);
    }
    
    private ClientTransport getClientTransport() {
        HttpClient httpClient = new HttpClient();
 
        try {   
            httpClient.start();
        } catch (Exception e) {
            logger.error("Http client start error: " + e.getMessage());
            return null;
        }

        // Prepare the transport
        Map<String, Object> options = new HashMap<String, Object>();
        
        //options.put("id", CometdClientUtils.getObject("deviceID"));
        //options.put("accessCode", CometdClientUtils.getObject("accessCode"));

        ClientTransport transport = LongPollingTransport.create(options, httpClient);
        
        return transport;
    }
    
    public boolean publishActivityMessage(Map<String, Object> message) {
       logger.debug("Publish activity message: " + message);
        if (clientSession != null && clientSession.isConnected() && clientSession.getChannel(CometdClientUtils.ACTIVITY_CHANNEL) != null) {
            clientSession.getChannel(CometdClientUtils.ACTIVITY_CHANNEL).publish(message);
            return true;
        }
        
        return false;
    }
    
    public boolean publishLogMessage(Map<String, Object> message) {
       logger.debug("Publish log message: " + message);
       if (clientSession != null && clientSession.isConnected() && clientSession.getChannel(CometdClientUtils.LOG_CHANNEL) != null) {
            clientSession.getChannel(CometdClientUtils.LOG_CHANNEL).publish(message);
            return true;
       }

       return false;
    }
}
