/*
 * Copyright 2007 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.client;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Provides access to browser cookies stored on the client. Because of browser
 * restrictions, you will only be able to access cookies associated with the
 * current page's domain.
 */
public class Cookies {

  /**
   * Cached copy of cookies.
   */
  static HashMap<String, String> cachedCookies = null;

  /**
   * Raw cookie string stored to allow cached cookies to be invalidated on
   * write.
   */
  // Used only in JSNI.
  static String rawCookies;

  /**
   * Flag that indicates whether cookies should be URIencoded (when set) and
   * URIdecoded (when retrieved). Defaults to URIencoding.
   */
  private static boolean uriEncoding = true;

  /**
   * Gets the cookie associated with the given name.
   * 
   * @param name the name of the cookie to be retrieved
   * @return the cookie's value, or <code>null</code> if the cookie doesn't
   *         exist
   */
  public static String getCookie(String name) {
    Map<String, String> cookiesMap = ensureCookies();
    return cookiesMap.get(name);
  }

  /**
   * Gets the names of all cookies in this page's domain.
   * 
   * @return the names of all cookies
   */
  public static Collection<String> getCookieNames() {
    return ensureCookies().keySet();
  }

  /**
   * Gets the URIencode flag.
   */
  public static boolean getUriEncode() {
    return uriEncoding;
  }

  /**
   * Removes the cookie associated with the given name.
   * 
   * @param name the name of the cookie to be removed
   */
  public static void removeCookie(String name) {
    if (uriEncoding) {
      uriEncode(name);
    }
    removeCookieNative(name);
  }

  /**
   * Removes the cookie associated with the given name.
   * 
   * @param name the name of the cookie to be removed
   * @param path the path to be associated with this cookie (which should match
   *          the path given in {@link #setCookie})
   */
  public static void removeCookie(String name, String path) {
    if (uriEncoding) {
      uriEncode(name);
    }
    removeCookieNative(name, path);
  }

  /**
   * Native method to remove a cookie with a path.
   */
  public static native void removeCookieNative(String name, String path) /*-{
    $doc.cookie = name + "=;path=" + path + ";expires=Fri, 02-Jan-1970 00:00:00 GMT"; 
  }-*/;

  /**
   * Sets a cookie. The cookie will expire when the current browser session is
   * ended.
   * 
   * @param name the cookie's name
   * @param value the cookie's value
   */
  public static void setCookie(String name, String value) {
    setCookie(name, value, null, null, null, false);
  }

  /**
   * Sets a cookie.
   * 
   * @param name the cookie's name
   * @param value the cookie's value
   * @param expires when the cookie expires
   */
  public static void setCookie(String name, String value, Date expires) {
    setCookie(name, value, expires, null, null, false);
  }

  /**
   * Sets a cookie. If uriEncoding is false, it checks the validity of name and
   * value. Name: Must conform to RFC 2965. Not allowed: = , ; white space. Also
   * can't begin with $. Value: No = or ;
   * 
   * @param name the cookie's name
   * @param value the cookie's value
   * @param expires when the cookie expires
   * @param domain the domain to be associated with this cookie
   * @param path the path to be associated with this cookie
   * @param secure <code>true</code> to make this a secure cookie (that is, only
   *          accessible over an SSL connection)
   */
  public static void setCookie(String name, String value, Date expires,
      String domain, String path, boolean secure) {
    if (uriEncoding) {
      uriEncode(name);
      uriEncode(value);
    } else if (!isValidCookieName(name) || !isValidCookieValue(value)) {
      throw new IllegalArgumentException("Illegal cookie format.");
    }
    setCookieImpl(name, value, (expires == null) ? 0 : expires.getTime(),
        domain, path, secure);
  }

  /**
   * Updates the URIencode flag and empties the cached cookies set.
   */
  public static void setUriEncode(boolean encode) {
    if (encode != uriEncoding) {
      uriEncoding = encode;
      cachedCookies = null;
    }
  }

  static native void loadCookies(HashMap<String, String> m) /*-{
    var docCookie = $doc.cookie;
    if (docCookie && docCookie != '') {
      var crumbs = docCookie.split('; ');
      for (var i = 0; i < crumbs.length; ++i) {
        var name, value;
        var eqIdx = crumbs[i].indexOf('=');
        if (eqIdx == -1) {
          name = crumbs[i];
          value = '';
        } else {
          name = crumbs[i].substring(0, eqIdx);
          value = crumbs[i].substring(eqIdx + 1);
        }
        if (@com.google.gwt.user.client.Cookies::uriEncoding) {
          try {
            name = decodeURIComponent(name);
          } catch (e) {
            // ignore error, keep undecoded name
          }
          try {
            value = decodeURIComponent(value);
          } catch (e) {
            // ignore error, keep undecoded value
          }
        }
        m.@java.util.Map::put(Ljava/lang/Object;Ljava/lang/Object;)(name,value);
      }
    }
  }-*/;

  private static HashMap<String, String> ensureCookies() {
    if (cachedCookies == null || needsRefresh()) {
      cachedCookies = new HashMap<String, String>();
      loadCookies(cachedCookies);
    }
    return cachedCookies;
  }

  /**
   * Checks whether a cookie name is valid: can't contain '=', ';', ',', or
   * whitespace. Can't begin with $.
   * 
   * @param name the cookie's name
   */
  private static boolean isValidCookieName(String name) {
    if (uriEncoding) {
      // check not necessary
      return true;
    } else if (name.contains("=") || name.contains(";") || name.contains(",")
        || name.startsWith("$") || name.matches(".*\\s+.*")) {
      return false;
    } else {
      return true;
    }
  }

  /**
   * Checks whether a cookie value is valid. A cookie cannot contain '=' or ';'.
   * 
   * @param value the cookie's value
   */
  private static boolean isValidCookieValue(String value) {
    if (uriEncoding) {
      // check not necessary
      return true;
    }
    if (value.contains("=") || value.contains(";")) {
      return false;
    } else {
      return true;
    }
  }

  private static native boolean needsRefresh() /*-{
    var docCookie = $doc.cookie;
        
    // Check to see if cached cookies need to be invalidated.
    if (docCookie != @com.google.gwt.user.client.Cookies::rawCookies) {  
      @com.google.gwt.user.client.Cookies::rawCookies = docCookie;
      return true;
    } else {
      return false;
    } 
  }-*/;

  /**
   * Native method to remove a cookie.
   */
  private static native void removeCookieNative(String name) /*-{
    $doc.cookie = name + "=;expires=Fri, 02-Jan-1970 00:00:00 GMT"; 
  }-*/;

  private static native void setCookieImpl(String name, String value,
      double expires, String domain, String path, boolean secure) /*-{
    var c = name + '=' + value;
    if ( expires )
      c += ';expires=' + (new Date(expires)).toGMTString();
    if (domain)
      c += ';domain=' + domain;
    if (path)
      c += ';path=' + path;
    if (secure)
      c += ';secure';

    $doc.cookie = c;
  }-*/;

  private static native String uriEncode(String s) /*-{
    return encodeURIComponent(s);
  }-*/;

  private Cookies() {
  }
}
