/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * 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                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.authentication.ui.login;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import com.vaadin.ui.JavaScript;
import com.vaadin.ui.JavaScriptFunction;

import elemental.json.JsonArray;

// TODO: Auto-generated Javadoc

/**
 * A helper that provides access to browser cookies.
 *
 * @author Matti Tahvonen
 * @author Joerg Riegel
 */
public class BrowserCookie {

	/**
	 * The Interface Callback.
	 */
	public interface Callback {

		/**
		 * On value detected.
		 *
		 * @param cookieName the cookie name
		 * @param value the value
		 */
		void onValueDetected(String cookieName, String value);
	}

	/**
	 * Sets the cookie.
	 *
	 * @param key the key
	 * @param value the value
	 */
	public static void setCookie(String key, String value) {
		setCookie(key, value, 999999999L, "/");
	}

	/**
	 * Sets the cookie.
	 *
	 * @param key the key
	 * @param value the value
	 * @param expires the expires
	 * @param path the path
	 */
	public static void setCookie(String key, String value, Long expires, String path) {
		DateFormat df = new SimpleDateFormat();
		Date now = new Date();
		long time = now.getTime();
		Long expireTime = time + expires;
		JavaScript.getCurrent().execute(
				String.format("document.cookie = \"%s=%s; expires=%s; path=%s\";", key,
						value, expireTime.toString(), path));
	}

	/**
	 * Detect cookie value.
	 *
	 * @param key the key
	 * @param callback the callback
	 */
	public static void detectCookieValue(String key, final Callback callback) {
		final String callbackid = "ccllbck"
				+ UUID.randomUUID().toString().substring(0, 8);
		JavaScript.getCurrent().addFunction(callbackid,
				new JavaScriptFunction() {

					/**
					 * 
					 */
					private static final long serialVersionUID = 6790247539398493857L;

					@Override
					public void call(JsonArray arguments) {
						if (arguments.length() == 0) {
							callback.onValueDetected(null, null);
							JavaScript.getCurrent().removeFunction(callbackid);
						} else {
							callback.onValueDetected(arguments.getString(0), arguments.getString(1));
						}
					}
				});

		JavaScript
				.getCurrent()
				.execute(
						String.format(
								  "var nameEQ = \"%2$s=\";"
								+ "var ca = document.cookie.split(';');"
								+ "for(var i=0;i < ca.length;i++) {"
								+ "		var c = ca[i];"
								+ "		while (c.charAt(0)==' ') "
								+ "			c = c.substring(1,c.length); "
								+ "		if (c.indexOf(nameEQ) == 0) {"
								+ "			%1$s( \"%2$s\", c.substring(nameEQ.length,c.length)); "
								+ "			break;"
								+ "		}"
								+ "} "
								+ "%1$s();",
								callbackid, key));

	}
}
