/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation 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
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.help.internal.webapp.servlet;

import java.io.*;
import java.util.HashSet;

import javax.servlet.http.*;

import org.eclipse.help.internal.webapp.*;
import org.eclipse.help.internal.webapp.data.*;

/**
 * Utilities for working with cookies
 *
 * @since 3.0
 */
public class CookieUtil {
	private static final int COOKIE_LIFE = 5 * 365 * 24 * 60 * 60;
	private static final int MAX_COOKIE_PAYLOAD = 4096
			- "wset_contents01=".length() - "81920<".length() - 1; //$NON-NLS-1$ //$NON-NLS-2$

	/**
	 * @return null or String
	 */
	public static String getCookieValue(String name, HttpServletRequest request) {
		String ret = null;
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				if (name.equals(cookie.getName())) {
					ret = cookie.getValue();
					break;
				}
			}
		}
		if (HelpWebappPlugin.DEBUG_WORKINGSETS) {
			System.out.println("CookieUtil.getCookieValue(" //$NON-NLS-1$
					+ name + ", " //$NON-NLS-1$
					+ request.getRequestURI() + ") returning " //$NON-NLS-1$
					+ ret);
		}
		return ret;
	}

	public static void setCookieValue(String name, String value,
			HttpServletRequest request, HttpServletResponse response) {
		Cookie cookie = new Cookie(name, value);
		cookie.setMaxAge(COOKIE_LIFE);

		if ( needsCookiePath(request)) {
			cookie.setPath(getCookiePath(request)); // Only set path if necessary
		}
		response.addCookie(cookie);
		if (HelpWebappPlugin.DEBUG_WORKINGSETS) {
			System.out
					.println("CookieUtil.setCookieValue(" + name + ", " + value + ",...)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
	}

	public static void setCookieValueWithoutPath(String name, String value,
			HttpServletRequest request, HttpServletResponse response ) {
		Cookie cookie = new Cookie(name, value);
		cookie.setMaxAge(COOKIE_LIFE);

		response.addCookie(cookie);
		if (HelpWebappPlugin.DEBUG_WORKINGSETS) {
			System.out
					.println("CookieUtil.setCookieValueWithoutPath(" + name + ", " + value + ",...)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
	}

	private static boolean needsCookiePath(HttpServletRequest request) {
		// All cookies should be at the same path level as the context ( /help )
		// The cookie path needs to be set if there are more path segments
		// between the context path and file name
		String requestURI = request.getRequestURI();
		String contextPath = request.getContextPath();
		return requestURI.indexOf('/', contextPath.length() + 1) > 0;
	}

	private static String getCookiePath(HttpServletRequest request) {
		return request.getContextPath() + '/';
	}

	public static void deleteCookie(String name, HttpServletRequest request, HttpServletResponse response) {
		deleteCookieUsingPath(name, request, response, getCookiePath(request));
	}

	protected static void deleteCookieUsingPath(String name, HttpServletRequest request,
			HttpServletResponse response, String cookiePath) {
		Cookie cookie = new Cookie(name, ""); //$NON-NLS-1$
		String requestURI = request.getRequestURI();
		if (!(requestURI.startsWith(cookiePath) && requestURI.indexOf('/', cookiePath.length() + 1) == -1)) {
		     cookie.setPath(cookiePath);
	    }
		cookie.setMaxAge(0);
		response.addCookie(cookie);
	}

	public static void deleteObsoleteCookies(HttpServletRequest request, HttpServletResponse response) {
		Cookie[] cookies = request.getCookies();
		HashSet<String> cookiesToKeep= new HashSet<String>();
		HashSet<String> cookiesToDelete = new HashSet<String>();
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				    String name = cookie.getName();
				    if (isObsoleteCookie(name) || cookiesToKeep.contains(name)) {
				    	cookiesToDelete.add(name);
				    }
					cookiesToKeep.add(name); {
				}
			}

			for (String name : cookiesToDelete) {
				deleteCookieUsingPath(name, request, response, request.getContextPath() + "/advanced/"); //$NON-NLS-1$
				deleteCookieUsingPath(name, request, response, "/"); //$NON-NLS-1$
			}
		}
	}

	/*
	 * Is this one of the cookies that was used before Eclipse 3.6 of the
	 * form wset_nn
	 */
	private static boolean isObsoleteCookie(String name) {
		final String WSET_PREFIX = "wset"; //$NON-NLS-1$
		if (!name.startsWith(WSET_PREFIX)) {
			return false;
		}
		for (int i = WSET_PREFIX.length(); i < name.length(); i++) {
			char suffixChar = name.charAt(i);
			if (suffixChar < '0' || suffixChar > '9') {
				return false;
			}
		}
		return true;
	}

	/**
	 * Saves string in multiple browser cookies. Cookies can store limited
	 * length string. This method will attemt to split string among multiple
	 * cookies. The following cookies will be set name1=length <substing1
	 * name2=substring2 ... namen=substringn
	 *
	 * @param data
	 *            a string containing legal characters for cookie value
	 * @throws IOException
	 *             when data is too long.
	 */
	public static void saveString(String name, String data, int maxCookies,
			HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		int len = data.length();
		int n = len / MAX_COOKIE_PAYLOAD;
		if (n > maxCookies) {
			throw new IOException(WebappResources.getString(
					"CookieUtil.tooManyCookiesNeeded", UrlUtil.getLocaleObj( //$NON-NLS-1$
							request, response)));
		}
		for (int i = 1; i <= n; i++) {
			if (i == 1) {
				setCookieValue(name + "1", //$NON-NLS-1$
						len + "<" + data.substring(0, MAX_COOKIE_PAYLOAD), //$NON-NLS-1$
						request, response);
			} else {
				setCookieValue(name + i, data.substring(MAX_COOKIE_PAYLOAD
						* (i - 1), MAX_COOKIE_PAYLOAD * i), request, response);
			}
		}
		if (len % MAX_COOKIE_PAYLOAD > 0) {
			if (n == 0) {
				setCookieValue(name + "1", //$NON-NLS-1$
						len + "<" + data.substring(0, len), //$NON-NLS-1$
						request, response);
			} else {
				setCookieValue(name + (n + 1), data.substring(
						MAX_COOKIE_PAYLOAD * n, len), request, response);
			}
		}

		// if using less cookies than maximum, delete not needed cookies from
		// last time
		for (int i = n + 1; i <= maxCookies; i++) {
			if (i == n + 1 && len % MAX_COOKIE_PAYLOAD > 0) {
				continue;
			}
			if (getCookieValue(name + i, request) != null) {
				deleteCookie(name + i, request, response);
			} else {
				break;
			}
		}
	}
	/**
	 * @return null or String
	 */
	public static String restoreString(String name, HttpServletRequest request) {
		String value1 = CookieUtil.getCookieValue(name + "1", request); //$NON-NLS-1$
		if (value1 == null) {
			// no cookie
			return null;
		}
		String lengthAndSubstring1[] = value1.split("<"); //$NON-NLS-1$
		if (lengthAndSubstring1.length < 2) {
			return null;
		}
		int len = 0;
		try {
			len = Integer.parseInt(lengthAndSubstring1[0]);
		} catch (NumberFormatException nfe) {
			return null;
		}
		if (len <= 0) {
			return null;
		}
		StringBuffer data = new StringBuffer(len);
		data.append(lengthAndSubstring1[1]);
		int n = len / MAX_COOKIE_PAYLOAD;
		for (int i = 2; i <= n; i++) {
			String substring = CookieUtil.getCookieValue(name + i, request);
			if (substring == null) {
				return null;
			}
			data.append(substring);
		}
		if (len % MAX_COOKIE_PAYLOAD > 0 && n > 0) {
			String substring = CookieUtil.getCookieValue(name + (n + 1),
					request);
			if (substring == null) {
				return null;
			}
			data.append(substring);
		}

		if (data.length() != len) {
			return null;
		}

		return data.toString();
	}
}
