package tachyon.master;

import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * Base object for all Json objects in Tachyon.
 */
abstract class JsonObject {
  /** Creates a JSON ObjectMapper configured not to close the underlying stream. */
  public static ObjectMapper createObjectMapper() {
    // TODO: Could disable field name quoting, though this would produce technically invalid JSON
    // See: JsonGenerator.QUOTE_FIELD_NAMES and JsonParser.ALLOW_UNQUOTED_FIELD_NAMES
    return new ObjectMapper().configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false).configure(
        SerializationFeature.CLOSE_CLOSEABLE, false);
  }

  private static final ObjectMapper OBJECT_MAPPER = createObjectMapper();

  public Map<String, Object> parameters = Maps.newHashMap();

  /**
   * Generic parameter getter, useful for custom classes or enums.
   * Use a more specific getter, like getLong(), when available.
   */
  public <T> T get(String name, Class<T> clazz) {
    Object value = parameters.get(name);
    try {
      String stringValue = OBJECT_MAPPER.writeValueAsString(value);
      return OBJECT_MAPPER.readValue(stringValue.getBytes(), clazz);
    } catch (Exception e) {
      // fail, lets try cast it
      return (T) value;
    }
  }

  public Boolean getBoolean(String name) {
    return this.get(name, Boolean.class);
  }

  /** Deserializes a base64-encoded String as a ByteBuffer. */
  public ByteBuffer getByteBuffer(String name) {
    String byteString = get(name, String.class);
    if (byteString == null) {
      return null;
    }

    return ByteBuffer.wrap(Base64.decodeBase64(byteString));
  }

  /** Deserializes a list of base64-encoded Strings as a list of ByteBuffers. */
  @SuppressWarnings("unchecked")
  public List<ByteBuffer> getByteBufferList(String name) {
    List<String> byteStrings = (List<String>) get(name, List.class);
    if (byteStrings == null) {
      return null;
    }

    List<ByteBuffer> buffers = Lists.newArrayListWithCapacity(byteStrings.size());
    for (String byteString : byteStrings) {
      buffers.add(ByteBuffer.wrap(Base64.decodeBase64(byteString)));
    }
    return buffers;
  }

  public Integer getInt(String name) {
    return this.get(name, Number.class).intValue();
  }

  /**
   * Deserializes the parameter as a long.
   * Use of this function is necessary when dealing with longs, as they may
   * have been deserialized as integers if they were sufficiently small.
   */
  public Long getLong(String name) {
    return this.get(name, Number.class).longValue();
  }

  public String getString(String name) {
    return this.get(name, String.class);
  }

  /** Adds the given named parameter to the Json object. Value must be JSON-serializable. */
  public JsonObject withParameter(String name, Object value) {
    parameters.put(name, value);
    return this;
  }
}

@@ -1216,32 +1216,65 @@
 vailable.%0A   */%0A
+  @SuppressWarnings(%22unchecked%22)%0A
   public %3CT%3E T g

Revert "Remove unneded supressWarning annotation."