/*
 * Copyright 2010 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 elemental.json.impl;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import elemental.json.Json;
import elemental.json.JsonArray;
import elemental.json.JsonException;
import elemental.json.JsonObject;
import elemental.json.JsonValue;
import elemental.json.impl.JsonContext;

/**
 * Direct port of json2.js at http://www.json.org/json2.js to GWT.
 */
@Deprecated
public class JsonUtil {

  private static class StringifyJsonVisitor extends JsonVisitor {

    private static final Set<String> skipKeys;

    static {
      Set<String> toSkip = new HashSet<String>();
      toSkip.add("$H");
      toSkip.add("__gwt_ObjectId");
      skipKeys = Collections.unmodifiableSet(toSkip);
    }

    private String indentLevel;

    private Set<JsonValue> visited;

    private final String indent;

    private final StringBuilder sb;

    private final boolean pretty;

    public StringifyJsonVisitor(String indent, StringBuilder sb,
        boolean pretty) {
      this.indent = indent;
      this.sb = sb;
      this.pretty = pretty;
      indentLevel = "";
      visited = new HashSet<JsonValue>();
    }

    @Override
    public void endVisit(JsonArray array, JsonContext ctx) {
      if (pretty) {
        indentLevel = indentLevel
            .substring(0, indentLevel.length() - indent.length());
        sb.append('\n');
        sb.append(indentLevel);
      }
      sb.append("]");
      visited.remove(array);
    }

    @Override
    public void endVisit(JsonObject object, JsonContext ctx) {
      if (pretty) {
        indentLevel = indentLevel
            .substring(0, indentLevel.length() - indent.length());
        sb.append('\n');
        sb.append(indentLevel);
      }
      sb.append("}");
      visited.remove(object);
      assert !visited.contains(object);
    }

    @Override
    public void visit(double number, JsonContext ctx) {
      sb.append(Double.isInfinite(number) || Double.isNaN(number) ? "null" : format(number));
    }

    @Override
    public void visit(String string, JsonContext ctx) {
      sb.append(quote(string));
    }

    @Override
    public void visit(boolean bool, JsonContext ctx) {
      sb.append(bool);
    }

    @Override
    public boolean visit(JsonArray array, JsonContext ctx) {
      checkCycle(array);
      sb.append("[");
      if (pretty) {
        sb.append('\n');
        indentLevel += indent;
        sb.append(indentLevel);
      }
      return true;
    }

    @Override
    public boolean visit(JsonObject object, JsonContext ctx) {
      checkCycle(object);
      sb.append("{");
      if (pretty) {
        sb.append('\n');
        indentLevel += indent;
        sb.append(indentLevel);
      }
      return true;
    }

    @Override
    public boolean visitIndex(int index, JsonContext ctx) {
      commaIfNotFirst(ctx);
      return true;
    }

    @Override
    public boolean visitKey(String key, JsonContext ctx) {
      if ("".equals(key)) {
        return true;
      }
      // skip properties injected by GWT runtime on JSOs
      if (skipKeys.contains(key)) {
        return false;
      }
      commaIfNotFirst(ctx);
      sb.append(quote(key) + ":");
      if (pretty) {
        sb.append(' ');
      }
      return true;
    }

    @Override
    public void visitNull(JsonContext ctx) {
      sb.append("null");
    }

    private void checkCycle(JsonValue value) {
      if (visited.contains(value)) {
        throw new JsonException("Cycled detected during stringify");
      } else {
        visited.add(value);
      }
    }

    private void commaIfNotFirst(JsonContext ctx) {
      if (!ctx.isFirst()) {
        sb.append(",");
        if (pretty) {
          sb.append('\n');
          sb.append(indentLevel);
        }
      }
    }

    private String format(double number) {
      String n = String.valueOf(number);
      if (n.endsWith(".0")) {
        n = n.substring(0, n.length() - 2);
      }
      return n;
    }
  }

  /**
   * Convert special control characters into unicode escape format.
   */
  public static String escapeControlChars(String text) {
    StringBuilder toReturn = new StringBuilder();
    for (int i = 0; i < text.length(); i++) {
      char c = text.charAt(i);
      if (isControlChar(c)) {
        toReturn.append(escapeCharAsUnicode(c));
      } else {
        toReturn.append(c);
      }
    }
    return toReturn.toString();
  }

  public static <T extends JsonValue> T parse(String json) throws JsonException {
    return Json.instance().parse(json);
  }

  /**
   * Safely escape an arbitrary string as a JSON string literal.
   */
  public static String quote(String value) {
    StringBuilder toReturn = new StringBuilder("\"");
    for (int i = 0; i < value.length(); i++) {
      char c = value.charAt(i);

      String toAppend = String.valueOf(c);
      switch (c) {
        case '\b':
          toAppend = "\\b";
          break;
        case '\t':
          toAppend = "\\t";
          break;
        case '\n':
          toAppend = "\\n";
          break;
        case '\f':
          toAppend = "\\f";
          break;
        case '\r':
          toAppend = "\\r";
          break;
        case '"':
          toAppend = "\\\"";
          break;
        case '\\':
          toAppend = "\\\\";
          break;
        default:
          if (isControlChar(c)) {
            toAppend = escapeCharAsUnicode(c);
          }
      }
      toReturn.append(toAppend);
    }
    toReturn.append("\"");
    return toReturn.toString();
  }

  /**
   * Converts a Json Object to Json format.
   *
   * @param jsonValue  json object to stringify
   * @return json formatted string
   */
  public static String stringify(JsonValue jsonValue) {
    return stringify(jsonValue, 0);
  }

  /**
   * Converts a JSO to Json format.
   *
   * @param jsonValue    json object to stringify
   * @param spaces number of spaces to indent in pretty print mode
   * @return json formatted string
   */
  public static String stringify(JsonValue jsonValue, int spaces) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < spaces; i++) {
      sb.append(' ');
    }
    return stringify(jsonValue, sb.toString());
  }

  /**
   * Converts a Json object to Json formatted String.
   *
   * @param jsonValue    json object to stringify
   * @param indent optional indention prefix for pretty printing
   * @return json formatted string
   */
  public static String stringify(JsonValue jsonValue, final String indent) {
    final StringBuilder sb = new StringBuilder();
    final boolean isPretty = indent != null && !"".equals(indent);

    new StringifyJsonVisitor(indent, sb, isPretty).accept(jsonValue);
    return sb.toString();
  }

  /**
   * Turn a single unicode character into a 32-bit unicode hex literal.
   */
  private static String escapeCharAsUnicode(char toEscape) {
    String hexValue = Integer.toString(toEscape, 16);
    int padding = 4 - hexValue.length();
    return "\\u" + ("0000".substring(0, padding)) + hexValue;
  }

  private static boolean isControlChar(char c) {
    return (c >= 0x00 && c <= 0x1f)  
        || (c >= 0x7f && c <= 0x9f) 
        || c == '\u00ad' || c == '\u070f' || c == '\u17b4' || c == '\u17b5'
        || c == '\ufeff' 
        || (c >= '\u0600' && c <= '\u0604')
        || (c >= '\u200c' && c <= '\u200f')
        || (c >= '\u2028' && c <= '\u202f')
        || (c >= '\u2060' && c <= '\u206f')
        || (c >= '\ufff0' && c <= '\uffff');
  }
}
