/*
 * 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;

  /**
   * Indicates whether or not cookies are enabled.
   */
  private static boolean isCookieEnabled = false;

  /**
   * Indicates whether or not we've checked if cookies are enabled.
   */
  private static boolean isCookieChecked = false;

  /**
   * 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;
  }

  /**
   * Checks whether or not cookies are enabled or disabled.
   * 
   * @return true if a cookie can be set, false if not
   */
  public static boolean isCookieEnabled() {
    if (!isCookieChecked) {
      // The only way to know for sure that cookies are enabled is to set and
      // retrieve one. Checking navigator.cookieEnabled may return the wrong
      // value if the browser has security software installed. In IE, it alerts
      // the user of an unspecified security risk when the app is embedded in an
      // iframe.
      isCookieChecked = true;
      Cookies.setCookie("__gwtCookieCheck", "isEnabled");
      isCookieEnabled = "isEnabled".equals(Cookies.getCookie("__gwtCookieCheck"));
      Cookies.removeCookie("__gwtCookieCheck");
    }
    return isCookieEnabled;
  }

  /**
   * 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) {
      name = 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) {
      name = 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) {
      name = uriEncode(name);
      value = uriEncode(value);
    } else if (!isValidCookieName(name)) {
      throw new IllegalArgumentException("Illegal cookie format: " + name + " is not a valid cookie name.");
    } else if (!isValidCookieValue(value)) {
      throw new IllegalArgumentException("Illegal cookie format: " + value + " is not a valid cookie value.");
    }
    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 = crumbs.length - 1; i >= 0; --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()) {
      HashMap<String, String> newCachedCookies = new HashMap<String, String>();
      loadCookies(newCachedCookies);
      cachedCookies = newCachedCookies;
    }
    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() {
  }
}
