/*
 * Copyright (C) 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.caliper;

import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

/**
 * Ordinarily serialization should be done within the class that is being serialized. However,
 * many of these classes are used by GWT, which dies when it sees Gson.
 */
public final class Json {
  /**
   * This Gson instance must be used when serializing a class that includes a Run as a member
   * or as a member of a member (etc.), otherwise the Map<Scenario, ScenarioResult> will not
   * be correctly serialized.
   */
  private static final Gson GSON_INSTANCE =
      new GsonBuilder()
          .registerTypeAdapter(Date.class, new DateTypeAdapter())
          .registerTypeAdapter(Run.class, new RunTypeAdapter())
          .registerTypeAdapter(Measurement.class, new MeasurementDeserializer())
          .create();

  public static Gson getGsonInstance() {
    return GSON_INSTANCE;
  }

  public static String measurementSetToJson(MeasurementSet measurementSet) {
    return new Gson().toJson(measurementSet);
  }

  /**
   * Attempts to extract a MeasurementSet from a string, assuming it is JSON. If this fails, it
   * tries to extract it from the string assuming it is a space-separated list of double values.
   */
  public static MeasurementSet measurementSetFromJson(String measurementSetJson) {
    try {
      return getGsonInstance().fromJson(measurementSetJson, MeasurementSet.class);
    } catch (JsonParseException e) {
      // might be an old MeasurementSet, so fall back on failure to the old, space separated
      // serialization method.
      try {
        String[] measurementStrings = measurementSetJson.split("\\s+");
        List<Measurement> measurements = new ArrayList<Measurement>();
        for (String s : measurementStrings) {
          measurements.add(
              new Measurement(ImmutableMap.of("ns", 1, "us", 1000, "ms", 1000000, "s", 1000000000),
              Double.valueOf(s), Double.valueOf(s)));
        }
        // seconds and variations is the default unit
        return new MeasurementSet(measurements.toArray(new Measurement[measurements.size()]));
      } catch (NumberFormatException ignore) {
        throw new IllegalArgumentException("Not a measurement set: " + measurementSetJson);
      }
    }
  }

  public static MeasurementSet measurementSetFromJson(JsonObject measurementSetJson) {
    return getGsonInstance().fromJson(measurementSetJson, MeasurementSet.class);
  }

  /**
   * Backwards compatibility!
   */
  private static class MeasurementDeserializer implements JsonDeserializer<Measurement> {
    @Override public Measurement deserialize(JsonElement jsonElement, Type type,
        JsonDeserializationContext context) throws JsonParseException {
      JsonObject obj = jsonElement.getAsJsonObject();
      if (obj.has("raw") && obj.has("processed")) {
        return new Measurement(
            context.<Map<String, Integer>>deserialize(obj.get("unitNames"),
                new TypeToken<Map<String, Integer>>() {}.getType()),
            context.<Double>deserialize(obj.get("raw"), Double.class),
            context.<Double>deserialize(obj.get("processed"), Double.class));
      }
      if (obj.has("nanosPerRep") && obj.has("unitsPerRep") && obj.has("unitNames")) {
        return new Measurement(
            context.<Map<String, Integer>>deserialize(obj.get("unitNames"),
                new TypeToken<Map<String, Integer>>() {}.getType()),
            context.<Double>deserialize(obj.get("nanosPerRep"), Double.class),
            context.<Double>deserialize(obj.get("unitsPerRep"), Double.class));
      }
      throw new JsonParseException(obj.toString());
    }
  }

  /**
   * This adapter is necessary because gson doesn't handle Maps more complex than Map<String, ...>
   * in a useful way. For example, Map<Scenario, ScenarioResult>'s serialized version simply uses
   * Scenario.toString() as the keys. This adapter stores this Map as lists of
   * KeyValuePair<Scenario, ScenarioResult> instead, to preserve the Scenario objects on
   * deserialization.
   */
  private static class RunTypeAdapter implements JsonSerializer<Run>, JsonDeserializer<Run> {

    @Override public Run deserialize(JsonElement jsonElement, Type type,
        JsonDeserializationContext context) throws JsonParseException {

      List<KeyValuePair<Scenario, ScenarioResult>> mapList = context.deserialize(
          jsonElement.getAsJsonObject().get("measurements"),
          new TypeToken<List<KeyValuePair<Scenario, ScenarioResult>>>() {}.getType());
      Map<Scenario, ScenarioResult> measurements = new LinkedHashMap<Scenario, ScenarioResult>();
      for (KeyValuePair<Scenario, ScenarioResult> entry : mapList) {
        measurements.put(entry.getKey(), entry.getValue());
      }

      String benchmarkName =
          context.deserialize(jsonElement.getAsJsonObject().get("benchmarkName"), String.class);

      Date executedTimestamp = context.deserialize(
          jsonElement.getAsJsonObject().get("executedTimestamp"), Date.class);

      return new Run(measurements, benchmarkName, executedTimestamp);
    }

    @Override public JsonElement serialize(Run run, Type type, JsonSerializationContext context) {
      JsonObject result = new JsonObject();
      result.add("benchmarkName", context.serialize(run.getBenchmarkName()));
      result.add("executedTimestamp", context.serialize(run.getExecutedTimestamp()));

      List<KeyValuePair<Scenario, ScenarioResult>> mapList =
          new ArrayList<KeyValuePair<Scenario, ScenarioResult>>();
      for (Map.Entry<Scenario, ScenarioResult> entry : run.getMeasurements().entrySet()) {
        mapList.add(new KeyValuePair<Scenario, ScenarioResult>(entry.getKey(), entry.getValue()));
      }
      result.add("measurements", context.serialize(mapList,
          new TypeToken<List<KeyValuePair<Scenario, ScenarioResult>>>() {}.getType()));

      return result;
    }
  }

  private static class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
    private final DateFormat dateFormat;

    private DateTypeAdapter() {
      dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz", Locale.US);
      dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    }

    @Override public synchronized JsonElement serialize(Date date, Type type,
        JsonSerializationContext jsonSerializationContext) {
      return new JsonPrimitive(dateFormat.format(date));
    }

    @Override public synchronized Date deserialize(JsonElement jsonElement, Type type,
        JsonDeserializationContext jsonDeserializationContext) {
      String dateString = jsonElement.getAsString();
      // first try to parse as an ISO 8601 date
      try {
        return dateFormat.parse(dateString);
      } catch (ParseException ignored) {
      }
      // next, try a GSON-style locale-specific dates (for Caliper r282 and earlier)
      try {
        return DateFormat.getDateTimeInstance().parse(dateString);
      } catch (ParseException ignored) {
      }
      throw new JsonParseException(dateString);
    }
  }

  /**
   * This is similar to the Map.Entry class, but is necessary since Entrys are not supported
   * by gson.
   */
  private static class KeyValuePair<K, V> {
    private K k;
    private V v;

    KeyValuePair(K k, V v) {
      this.k = k;
      this.v = v;
    }

    public K getKey() {
      return k;
    }

    public V getValue() {
      return v;
    }

    @SuppressWarnings("unused")
    private KeyValuePair() {} // for gson
  }

  private Json() {} // static class
}
