/*
 * Copyright 2009 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.core.client;

/**
 * Provides JSON-related utility methods.
 */
public class JsonUtils {

  /**
   * Converts a value to JSON.
   */
  public static native String stringify(JavaScriptObject obj) /*-{
    return JSON.stringify(obj);
  }-*/;

  /**
   * Converts a value to JSON.
   *
   * @param space controls the spacing in the final string. Successive levels in the stringification
   *        will each be indented by this string (or the first ten characters of it).
   */
  public static native String stringify(JavaScriptObject obj, String space) /*-{
    return JSON.stringify(obj, null, space);
  }-*/;

  /**
   * Escapes characters within a JSON string than cannot be passed directly to
   * eval(). Control characters, quotes and backslashes are not affected.
   */
  public static native String escapeJsonForEval(String toEscape) /*-{
    var escapeTable = @JsonUtils::getEscapeTable()();
    var s = toEscape.replace(/[\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200b-\u200f\u2028-\u202e\u2060-\u2064\u206a-\u206f\ufeff\ufff9-\ufffb]/g, function(x) {
      return @JsonUtils::escapeChar(*)(x, escapeTable);
    });
    return s;
  }-*/;

  /**
   * Returns a quoted, escaped JSON String.
   */
  public static native String escapeValue(String toEscape) /*-{
    var escapeTable = @JsonUtils::getEscapeTable()();
    var s = toEscape.replace(/[\x00-\x1f\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200b-\u200f\u2028-\u202e\u2060-\u2064\u206a-\u206f\ufeff\ufff9-\ufffb"\\]/g, function(x) {
      return @JsonUtils::escapeChar(*)(x, escapeTable);
    });
    return "\"" + s + "\"";
  }-*/;

  /**
   * Evaluates a JSON expression safely. The payload must evaluate to an Object
   * or an Array (not a primitive or a String).
   * 
   * @param <T> The type of JavaScriptObject that should be returned
   * @param json The source JSON text
   * @return The evaluated object
   * 
   * @throws IllegalArgumentException if the input is not valid JSON
   */
  public static native <T extends JavaScriptObject> T safeEval(String json) /*-{
    try {
      return JSON.parse(json);
    } catch (e) {
      return @JsonUtils::throwIllegalArgumentException(*)("Error parsing JSON: " + e, json);
    }
  }-*/;
  
  /**
   * Returns true if the given JSON string may be safely evaluated by {@code
   * eval()} without undersired side effects or security risks. Note that a true
   * result from this method does not guarantee that the input string is valid
   * JSON.  This method does not consider the contents of quoted strings; it
   * may still be necessary to perform escaping prior to evaluation for correct
   * results.
   * 
   * <p> The technique used is taken from <a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>.
   */
  public static native boolean safeToEval(String text) /*-{
    // Remove quoted strings and disallow anything except:
    //
    // 1) symbols and brackets ,:{}[]
    // 2) numbers: digits 0-9, ., -, +, e, and E
    // 3) literal values: 'null', 'true' and 'false' = [aeflnr-u]
    // 4) whitespace: ' ', '\n', '\r', and '\t'
    return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(text.replace(/"(\\.|[^"\\])*"/g, '')));
  }-*/;
  
  /**
   * Evaluates a JSON expression using {@code eval()}. This method does not
   * validate the JSON text and should only be used on JSON from trusted
   * sources. The payload must evaluate to an Object or an Array (not a
   * primitive or a String).
   * 
   * @param <T> The type of JavaScriptObject that should be returned
   * @param json The source JSON text
   * @return The evaluated object
   */
  public static native <T extends JavaScriptObject> T unsafeEval(String json) /*-{
    var escaped = @JsonUtils::escapeJsonForEval(Ljava/lang/String;)(json);
    try {
      return eval('(' + escaped + ')');
    } catch (e) {
      return @JsonUtils::throwIllegalArgumentException(*)("Error parsing JSON: " + e, json);
    }
  }-*/;

  static void throwIllegalArgumentException(String message, String data) {
    throw new IllegalArgumentException(message + "\n" + data);
  }

  private static native String escapeChar(String c, JavaScriptObject escapeTable) /*-{
    var lookedUp = @JsonUtils::escapeTable[c.charCodeAt(0)];
    return (lookedUp == null) ? c : lookedUp;
  }-*/;

  private static JavaScriptObject escapeTable; // Lazily initialized.

  private static JavaScriptObject getEscapeTable() {
    if (escapeTable == null) {
      escapeTable = initEscapeTable();
    }
    return escapeTable;
  }

  private static native JavaScriptObject initEscapeTable() /*-{
    var out = [
      "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005",
      "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\u000B",
      "\\f", "\\r", "\\u000E", "\\u000F", "\\u0010", "\\u0011",
      "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017",
      "\\u0018", "\\u0019", "\\u001A", "\\u001B", "\\u001C", "\\u001D",
      "\\u001E", "\\u001F"];
    out[34] = '\\"';
    out[92] = '\\\\';
    out[0xad] = '\\u00ad'; // Soft hyphen
    out[0x600] = '\\u0600'; // Arabic number sign
    out[0x601] = '\\u0601'; // Arabic sign sanah
    out[0x602] = '\\u0602'; // Arabic footnote marker
    out[0x603] = '\\u0603'; // Arabic sign safha
    out[0x6dd] = '\\u06dd'; // Arabic and of ayah
    out[0x70f] = '\\u070f'; // Syriac abbreviation mark
    out[0x17b4] = '\\u17b4'; // Khmer vowel inherent aq
    out[0x17b5] = '\\u17b5'; // Khmer vowel inherent aa
    out[0x200b] = '\\u200b'; // Zero width space
    out[0x200c] = '\\u200c'; // Zero width non-joiner
    out[0x200d] = '\\u200d'; // Zero width joiner
    out[0x200e] = '\\u200e'; // Left-to-right mark
    out[0x200f] = '\\u200f'; // Right-to-left mark
    out[0x2028] = '\\u2028'; // Line separator
    out[0x2029] = '\\u2029'; // Paragraph separator
    out[0x202a] = '\\u202a'; // Left-to-right embedding
    out[0x202b] = '\\u202b'; // Right-to-left embedding
    out[0x202c] = '\\u202c'; // Pop directional formatting
    out[0x202d] = '\\u202d'; // Left-to-right override
    out[0x202e] = '\\u202e'; // Right-to-left override
    out[0x2060] = '\\u2060'; // Word joiner
    out[0x2061] = '\\u2061'; // Function application
    out[0x2062] = '\\u2062'; // Invisible times
    out[0x2063] = '\\u2063'; // Invisible separator
    out[0x2064] = '\\u2064'; // Invisible plus
    out[0x206a] = '\\u206a'; // Inhibit symmetric swapping
    out[0x206b] = '\\u206b'; // Activate symmetric swapping
    out[0x206c] = '\\u206c'; // Inherent Arabic form shaping
    out[0x206d] = '\\u206d'; // Activate Arabic form shaping
    out[0x206e] = '\\u206e'; // National digit shapes
    out[0x206f] = '\\u206f'; // Nominal digit shapes
    out[0xfeff] = '\\ufeff'; // Zero width no-break space
    out[0xfff9] = '\\ufff9'; // Intralinear annotation anchor
    out[0xfffa] = '\\ufffa'; // Intralinear annotation separator
    out[0xfffb] = '\\ufffb'; // Intralinear annotation terminator
    return out;
  }-*/;

  private JsonUtils() {
  }
}
