/*
 * Copyright 2015-present Facebook, 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.facebook.buck.json;

import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.hash.Hasher;

import java.util.Collection;
import java.util.Map;

import javax.annotation.Nullable;

/**
 * Hashes parsed JSON objects as returned by {@link RawParser}.
 */
public class JsonObjectHashing {
  private static enum HashedObjectType {
      BOOLEAN,
      DOUBLE,
      FLOAT,
      INTEGER,
      LIST,
      LONG,
      SHORT,
      STRING,
      MAP,
      NULL
  }

  // Utility class; do not instantiate.
  private JsonObjectHashing() { }

  /**
   * Given a {@link Hasher} and a parsed JSON object returned by
   * {@link RawParser#parseFromReader(java.io.Reader)}, updates the Hasher
   * with the contents of the JSON object.
   */
  public static void hashJsonObject(Hasher hasher, @Nullable Object obj) {
    if (obj instanceof Map) {
      Map<?, ?> map = (Map<?, ?>) obj;
      ImmutableSortedMap.Builder<String, Optional<Object>> sortedMapBuilder =
          ImmutableSortedMap.naturalOrder();
      for (Map.Entry<?, ?> entry : map.entrySet()) {
        Object key = entry.getKey();
        if (!(key instanceof String)) {
          throw new RuntimeException(
              String.format(
                  "Keys of JSON maps are expected to be strings. Actual type: %s, contents: %s",
                  key.getClass().getName(),
                  key));
        }
        Object value = entry.getValue();
        if (value != null) {
          sortedMapBuilder.put((String) key, Optional.of(value));
        } else {
          sortedMapBuilder.put((String) key, Optional.absent());
        }
      }
      ImmutableSortedMap<String, Optional<Object>> sortedMap = sortedMapBuilder.build();
      hasher.putInt(HashedObjectType.MAP.ordinal());
      hasher.putInt(sortedMap.size());
      for (Map.Entry<String, Optional<Object>> entry : sortedMap.entrySet()) {
        hashJsonObject(hasher, entry.getKey());
        if (entry.getValue().isPresent()) {
          hashJsonObject(hasher, entry.getValue().get());
        } else {
          hashJsonObject(hasher, null);
        }
      }
    } else if (obj instanceof Collection) {
      Collection<?> collection = (Collection<?>) obj;
      hasher.putInt(HashedObjectType.LIST.ordinal());
      hasher.putInt(collection.size());
      for (Object collectionEntry : collection) {
        hashJsonObject(hasher, collectionEntry);
      }
    } else if (obj instanceof String) {
      hasher.putInt(HashedObjectType.STRING.ordinal());
      byte[] stringBytes = ((String) obj).getBytes(Charsets.UTF_8);
      hasher.putInt(stringBytes.length);
      hasher.putBytes(stringBytes);
    } else if (obj instanceof Boolean) {
      hasher.putInt(HashedObjectType.BOOLEAN.ordinal());
      hasher.putBoolean((boolean) obj);
    } else if (obj instanceof Number) {
      // This is gross, but it mimics the logic in RawParser.
      Number number = (Number) obj;
      if (number.longValue() == number.doubleValue()) {
        hasher.putInt(HashedObjectType.LONG.ordinal());
        hasher.putLong(number.longValue());
      } else {
        hasher.putInt(HashedObjectType.DOUBLE.ordinal());
        hasher.putDouble(number.doubleValue());
      }
    } else if (obj instanceof Void || obj == null) {
      hasher.putInt(HashedObjectType.NULL.ordinal());
    } else {
      throw new RuntimeException(
          String.format("Unsupported object %s (class %s)", obj, obj.getClass()));
    }
  }
}
