/**
 * Copyright (c) 2010-2014, openHAB.org 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
 */
package org.openhab.io.rest.internal.filter;


import javax.servlet.http.HttpServletRequest;

import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.BroadcastFilter.BroadcastAction.ACTION;
import org.atmosphere.cpr.PerRequestBroadcastFilter;
import org.codehaus.jackson.map.ObjectMapper;
import org.openhab.io.rest.internal.listeners.ResourceStateChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * This Filter prevents duplicate broadcasts   
 *  
 * @author Oliver Mazur
 * @since 1.0
 *
 *
 */
public class DuplicateBroadcastProtectionFilter implements PerRequestBroadcastFilter {

	private static final Logger logger = LoggerFactory.getLogger(DuplicateBroadcastProtectionFilter.class);
	
	@Override
	public BroadcastAction filter(Object arg0, Object message) {
		return new BroadcastAction(ACTION.CONTINUE, message);
	}

	@Override
	public BroadcastAction filter(AtmosphereResource resource, Object originalMessage, Object message) {
		final  HttpServletRequest request = resource.getRequest();
		
		try {	
			if(!isDoubleBroadcast(request,message ) ){
				return new BroadcastAction(ACTION.CONTINUE,  message);
			}
			else {
				return new BroadcastAction(ACTION.ABORT,  message);
			}
			
		} catch (Exception e) {
			logger.error(e.getMessage());
			return new BroadcastAction(ACTION.ABORT,  message);
		} 
		
	}
	
	private boolean isDoubleBroadcast(HttpServletRequest request, Object responseEntity){
		String clientId = request.getHeader("X-Atmosphere-tracking-id");
		
		// return false if the X-Atmosphere-tracking-id is not set
		if(clientId == null || clientId.isEmpty()){
			return false;
		}
		ObjectMapper mapper = new ObjectMapper();
		try{
			String firedResponse =  mapper.writeValueAsString(ResourceStateChangeListener.getMap().put(clientId, responseEntity)); 
			String responseValue =  mapper.writeValueAsString(responseEntity);
            if(responseValue.equals(firedResponse)) {
            	return true;
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		} 
        return false;
	}

}

@@ -356,24 +356,118 @@
 ilter;%0D%0A%0D%0A%0D%0A
+import java.util.concurrent.ConcurrentHashMap;%0D%0Aimport java.util.concurrent.ConcurrentMap;%0D%0A%0D%0A
 import javax
@@ -550,16 +550,70 @@
 ource;%0D%0A
+import org.atmosphere.cpr.AtmosphereResourceFactory;%0D%0A
 import o
@@ -2223,16 +2223,361 @@
 %09%09try%7B%0D%0A
+%09%09%09ConcurrentMap%3CString, Object%3E resources = ResourceStateChangeListener.getMap();%0D%0A%09%09%09for(String uuid : resources.keySet())%7B%0D%0A%09%09%09%09AtmosphereResource resource = AtmosphereResourceFactory.getDefault().find(uuid);%0D%0A%09%09%09%09if(resource == null)%7B%0D%0A%09%09%09%09%09logger.trace(%22removing %7B%7D from duplicate cache%22, uuid);%0D%0A%09%09%09%09%09resources.remove(uuid);%0D%0A%09%09%09%09%7D%0D%0A%09%09%09%7D%0D%0A
 %09%09%09Strin
@@ -2818,16 +2818,87 @@
 se)) %7B%0D%0A
+            %09logger.trace(%22Duplicate message for uuid %7B%7D%22, clientId);%0D%0A
         

Clear cache of invalid uuids