/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.waveprotocol.box.server.rpc;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.protobuf.Message;
import com.google.protobuf.MessageLite;

import org.waveprotocol.box.common.comms.WaveClientRpc.DocumentSnapshot;
import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolAuthenticate;
import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolAuthenticationResult;
import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolOpenRequest;
import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolSubmitRequest;
import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolSubmitResponse;
import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolWaveletUpdate;
import org.waveprotocol.box.common.comms.WaveClientRpc.WaveViewSnapshot;
import org.waveprotocol.box.common.comms.WaveClientRpc.WaveletSnapshot;
import org.waveprotocol.box.common.comms.proto.DocumentSnapshotProtoImpl;
import org.waveprotocol.box.common.comms.proto.ProtocolAuthenticateProtoImpl;
import org.waveprotocol.box.common.comms.proto.ProtocolAuthenticationResultProtoImpl;
import org.waveprotocol.box.common.comms.proto.ProtocolOpenRequestProtoImpl;
import org.waveprotocol.box.common.comms.proto.ProtocolSubmitRequestProtoImpl;
import org.waveprotocol.box.common.comms.proto.ProtocolSubmitResponseProtoImpl;
import org.waveprotocol.box.common.comms.proto.ProtocolWaveletUpdateProtoImpl;
import org.waveprotocol.box.common.comms.proto.WaveViewSnapshotProtoImpl;
import org.waveprotocol.box.common.comms.proto.WaveletSnapshotProtoImpl;
import org.waveprotocol.box.profile.ProfilesProto.ProfileResponse;
import org.waveprotocol.box.profile.proto.ProfileResponseProtoImpl;
import org.waveprotocol.box.search.SearchProto.SearchResponse;
import org.waveprotocol.box.search.proto.SearchResponseProtoImpl;
import org.waveprotocol.box.server.rpc.Rpc.CancelRpc;
import org.waveprotocol.box.server.rpc.Rpc.RpcFinished;
import org.waveprotocol.box.server.rpc.proto.CancelRpcProtoImpl;
import org.waveprotocol.box.server.rpc.proto.RpcFinishedProtoImpl;
import org.waveprotocol.box.attachment.AttachmentProto.AttachmentsResponse;
import org.waveprotocol.box.attachment.proto.AttachmentsResponseProtoImpl;
import org.waveprotocol.wave.communication.gson.GsonException;
import org.waveprotocol.wave.communication.gson.GsonSerializable;
import org.waveprotocol.wave.communication.json.RawStringData;
import org.waveprotocol.wave.communication.proto.ProtoWrapper;

import java.util.Map;

/**
 * Serializes protos to/from JSON objects.
 * <p>
 * This class uses the PST-generated message classes to perform serialization
 * and deserialization.
 */
public final class ProtoSerializer {

  public static final class SerializationException extends Exception {
    public SerializationException(Exception cause) {
      super(cause);
    }

    public SerializationException(String message) {
      super(message);
    }
  }

  /**
   * Serializes protos of a particular type to/from JSON objects.
   *
   * @param <P> proto type
   * @param <D> GSON-based DTO wrapper type for a {@code P}
   */
  static final class ProtoImplSerializer<
      P extends Message,
      D extends ProtoWrapper<P> & GsonSerializable> {
    private final Class<P> protoClass;
    private final Class<D> dtoClass;

    ProtoImplSerializer(Class<P> protoClass, Class<D> dtoClass) {
      this.protoClass = protoClass;
      this.dtoClass = dtoClass;
    }

    static <P extends Message, D extends ProtoWrapper<P> & GsonSerializable>
        ProtoImplSerializer<P, D> of(
        Class<P> protoClass, Class<D> dtoClass) {
      return new ProtoImplSerializer<P, D>(protoClass, dtoClass);
    }

    D newDto() throws SerializationException {
      try {
        return dtoClass.newInstance();
      } catch (InstantiationException e) {
        throw new SerializationException(e);
      } catch (IllegalAccessException e) {
        throw new SerializationException(e);
      }
    }

    JsonElement toGson(MessageLite proto, RawStringData data, Gson gson)
        throws SerializationException {
      Preconditions.checkState(protoClass.isInstance(proto));
      D dto = newDto();
      dto.setPB(protoClass.cast(proto));
      return dto.toGson(data, gson);
    }

    P fromJson(JsonElement json, RawStringData data, Gson gson) throws SerializationException {
      D dto = newDto();
      try {
        dto.fromGson(json, gson, data);
      } catch (GsonException e) {
        throw new SerializationException(e);
      }
      return dto.getPB();
    }
  }

  private final Gson gson = new Gson();
  private final Map<Class<?>, ProtoImplSerializer<?, ?>> byClass = Maps.newHashMap();
  private final Map<String, ProtoImplSerializer<?, ?>> byName = Maps.newHashMap();

  public ProtoSerializer() {
    init();
  }

  /** Adds the known proto types. */
  private void init() {
    // Note: this list is too inclusive, but has historically always been so.
    // The real list only needs about 5 protos, since only top-level rpc types
    // need to be here, not every single recursively reachable proto.
    add(ProtocolAuthenticate.class, ProtocolAuthenticateProtoImpl.class);
    add(ProtocolAuthenticationResult.class, ProtocolAuthenticationResultProtoImpl.class);
    add(ProtocolOpenRequest.class, ProtocolOpenRequestProtoImpl.class);
    add(ProtocolSubmitRequest.class, ProtocolSubmitRequestProtoImpl.class);
    add(ProtocolSubmitResponse.class, ProtocolSubmitResponseProtoImpl.class);
    add(ProtocolWaveletUpdate.class, ProtocolWaveletUpdateProtoImpl.class);
    add(WaveletSnapshot.class, WaveletSnapshotProtoImpl.class);
    add(DocumentSnapshot.class, DocumentSnapshotProtoImpl.class);
    add(WaveViewSnapshot.class, WaveViewSnapshotProtoImpl.class);

    add(CancelRpc.class, CancelRpcProtoImpl.class);
    add(RpcFinished.class, RpcFinishedProtoImpl.class);

    add(SearchResponse.class, SearchResponseProtoImpl.class);
    add(ProfileResponse.class, ProfileResponseProtoImpl.class);

    add(AttachmentsResponse.class, AttachmentsResponseProtoImpl.class);
  }

  /** Adds a binding between a proto class and a DTO message class. */
  private <P extends Message, D extends ProtoWrapper<P> & GsonSerializable> void add(
      Class<P> protoClass, Class<D> dtoClass) {
    ProtoImplSerializer<P, D> serializer = ProtoImplSerializer.of(protoClass, dtoClass);
    byClass.put(protoClass, serializer);
    byName.put(protoClass.getSimpleName(), serializer);
  }

  /**
   * Gets the serializer for a proto class. Never returns null.
   *
   * @throws SerializationException if there is no serializer for
   *         {@code protoClass}.
   */
  private <P extends Message, D extends ProtoWrapper<P> & GsonSerializable> ProtoImplSerializer<P, D> getSerializer(Class<P> protoClass)
      throws SerializationException {
    @SuppressWarnings("unchecked")
    // use of serializers map is safe.
    ProtoImplSerializer<P, D> serializer =
        (ProtoImplSerializer<P, D>) byClass.get(protoClass);
    if (serializer == null) {
      throw new SerializationException("Unknown proto class: " + protoClass.getName());
    }
    return serializer;
  }

  /**
   * Gets the serializer for a proto class name. Never returns null.
   *
   * @throws SerializationException if there is no serializer for
   *         {@code protoName}.
   */
  private <P extends Message> ProtoImplSerializer<P, ?> getSerializer(String protoName)
      throws SerializationException {
    @SuppressWarnings("unchecked")
    // use of serializers map is safe.
    ProtoImplSerializer<P, ?> serializer = (ProtoImplSerializer<P, ?>) byName.get(protoName);
    if (serializer == null) {
      throw new SerializationException("Unknown proto class: " + protoName);
    }
    return serializer;
  }

  /**
   * Serializes a proto to JSON. Only protos whose classes have been registered
   * will be serialized.
   *
   * @throws SerializationException if the class of {@code message} has not been
   *         registered.
   */
  public <P extends Message>JsonElement toJson(P message) throws SerializationException {
    return getSerializer(message.getClass()).toGson(message, null, gson);
  }

  /**
   * Deserializes a proto from JSON. Only protos whose classes have been
   * registered can be deserialized.
   *
   * @throws SerializationException if no class called {@code type} has been
   *         registered.
   */
  public Message fromJson(JsonElement json, String type) throws SerializationException {
    return getSerializer(type).fromJson(json, null, gson);
  }

  // Utility method for a test.
  @VisibleForTesting
  public <P extends Message> P fromJson(JsonElement json, Class<P> clazz)
      throws SerializationException {
    return getSerializer(clazz).fromJson(json, null, gson);
  }
}
