/*
 * 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 com.google.gwt.dev.json;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * JSON object.
 */
public class JsonObject implements JsonValue, Iterable<Pair<String, JsonValue>> {
  private static class Iter implements Iterator<Pair<String, JsonValue>> {
    private final Iterator<Map.Entry<String, JsonValue>> iter;

    Iter(Iterator<Map.Entry<String, JsonValue>> iter) {
      this.iter = iter;
    }

    public boolean hasNext() {
      return iter.hasNext();
    }

    public Pair<String, JsonValue> next() {
      final Map.Entry<String, JsonValue> entry = iter.next();
      return new Pair<String, JsonValue>(entry.getKey(), entry.getValue());
    }

    public void remove() {
      iter.remove();
    }
  }

  public static JsonObject create() {
    return new JsonObject();
  }

  /**
   * Creates a {@link JsonObject} from a valid JSON string. This routine expects
   * the first non-whitespace character to be '{', then reads a single encoded
   * object from the {@link Reader} and leaves the reader positioned after the
   * last '}' character.
   *
   * @param reader {@link Reader} positioned to contain a JSON object encoded as
   *          a string.
   * @return a valid {@link JsonObject} on success, throws exception on failure.
   * @throws JsonException The input string is not in valid JSON format.
   * @throws IOException An IO error was encountered before all of the string
   *           could be read.
   */
  public static JsonObject parse(Reader reader) throws JsonException,
      IOException {
    return JsonObject.parse(new Tokenizer(reader));
  }

  static JsonObject parse(Tokenizer tokenizer) throws IOException,
      JsonException {
    final JsonObject object = new JsonObject();
    int c = tokenizer.nextNonWhitespace();
    if (c != '{') {
      throw new JsonException("Payload does not begin with '{'.  Got " + c + "("
          + Character.valueOf((char)c) + ")");
    }

    while (true) {
      c = tokenizer.nextNonWhitespace();
      switch (c) {
        case '}':
          // We're done.
          return object;
        case '"':
          tokenizer.back(c);
          // Ready to start a key.
          final String key = tokenizer.nextString();
          if (tokenizer.nextNonWhitespace() != ':') {
            throw new JsonException("Invalid object: expecting \":\"");
          }
          // TODO(knorton): Make sure this key is not already set.
          object.put(key, tokenizer.nextValue());
          switch (tokenizer.nextNonWhitespace()) {
            case ',':
              break;
            case '}':
              return object;
            default:
              throw new JsonException("Invalid object: expecting } or ,");
          }
          break;
        case ',':
          break;
        default:
          throw new JsonException("Invalid object: ");
      }
    }
  }

  private final Map<String, JsonValue> properties = new HashMap<String, JsonValue>();

  public JsonObject() {
  }

  public JsonArray asArray() {
    return null;
  }

  public JsonBoolean asBoolean() {
    return null;
  }

  public JsonNumber asNumber() {
    return null;
  }

  public JsonObject asObject() {
    return this;
  }

  public JsonString asString() {
    return null;
  }

  public JsonObject copyDeeply() {
    final JsonObject copy = new JsonObject();
    for (Map.Entry<String, JsonValue> entry : properties.entrySet()) {
      final JsonValue value = entry.getValue();
      copy.properties.put(entry.getKey(), value == null ? null
          : value.copyDeeply());
    }
    return copy;
  }

  public JsonValue get(String key) {
    final JsonValue value = properties.get(key);
    return (value == null) ? JsonValue.NULL : value;
  }

  public boolean isArray() {
    return false;
  }

  public boolean isBoolean() {
    return false;
  }

  public boolean isEmpty() {
    return properties.isEmpty();
  }

  public boolean isNumber() {
    return false;
  }

  public boolean isObject() {
    return true;
  }

  public boolean isString() {
    return false;
  }

  public Iterator<Pair<String, JsonValue>> iterator() {
    return new Iter(properties.entrySet().iterator());
  }

  public void put(String key, boolean val) {
    put(key, JsonBoolean.create(val));
  }

  public void put(String key, double val) {
    put(key, JsonNumber.create(val));
  }

  public void put(String key, JsonValue val) {
    properties.put(key, val);
  }

  public void put(String key, long val) {
    put(key, JsonNumber.create(val));
  }

  public void put(String key, String val) {
    put(key, JsonString.create(val));
  }

  public void write(Writer writer) throws IOException {
    boolean first = true;
    writer.write('{');
    for (Map.Entry<String, JsonValue> e : properties.entrySet()) {
      if (!first) {
        writer.append(',');
      } else {
        first = false;
      }
      JsonString.write(e.getKey(), writer);
      writer.append(':');
      e.getValue().write(writer);
    }
    writer.write('}');
  }
}
