// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package com.google.protobuf;

/**
 * Grab-bag of utility functions useful when dealing with RPCs.
 *
 * @author kenton@google.com Kenton Varda
 */
public final class RpcUtil {
  private RpcUtil() {}

  /**
   * Take an {@code RpcCallback<Message>} and convert it to an
   * {@code RpcCallback} accepting a specific message type.  This is always
   * type-safe (parameter type contravariance).
   */
  @SuppressWarnings("unchecked")
  public static <Type extends Message> RpcCallback<Type>
  specializeCallback(final RpcCallback<Message> originalCallback) {
    return (RpcCallback<Type>)originalCallback;
    // The above cast works, but only due to technical details of the Java
    // implementation.  A more theoretically correct -- but less efficient --
    // implementation would be as follows:
    //   return new RpcCallback<Type>() {
    //     public void run(Type parameter) {
    //       originalCallback.run(parameter);
    //     }
    //   };
  }

  /**
   * Take an {@code RpcCallback} accepting a specific message type and convert
   * it to an {@code RpcCallback<Message>}.  The generalized callback will
   * accept any message object which has the same descriptor, and will convert
   * it to the correct class before calling the original callback.  However,
   * if the generalized callback is given a message with a different descriptor,
   * an exception will be thrown.
   */
  public static <Type extends Message>
  RpcCallback<Message> generalizeCallback(
      final RpcCallback<Type> originalCallback,
      final Class<Type> originalClass,
      final Type defaultInstance) {
    return new RpcCallback<Message>() {
      @Override
      public void run(final Message parameter) {
        Type typedParameter;
        try {
          typedParameter = originalClass.cast(parameter);
        } catch (ClassCastException ignored) {
          typedParameter = copyAsType(defaultInstance, parameter);
        }
        originalCallback.run(typedParameter);
      }
    };
  }

  /**
   * Creates a new message of type "Type" which is a copy of "source".  "source"
   * must have the same descriptor but may be a different class (e.g.
   * DynamicMessage).
   */
  @SuppressWarnings("unchecked")
  private static <Type extends Message> Type copyAsType(
      final Type typeDefaultInstance, final Message source) {
    return (Type) typeDefaultInstance
        .newBuilderForType().mergeFrom(source).build();
  }

  /**
   * Creates a callback which can only be called once.  This may be useful for
   * security, when passing a callback to untrusted code:  most callbacks do
   * not expect to be called more than once, so doing so may expose bugs if it
   * is not prevented.
   */
  public static <ParameterType>
    RpcCallback<ParameterType> newOneTimeCallback(
      final RpcCallback<ParameterType> originalCallback) {
    return new RpcCallback<ParameterType>() {
      private boolean alreadyCalled = false;

      @Override
      public void run(final ParameterType parameter) {
        synchronized (this) {
          if (alreadyCalled) {
            throw new AlreadyCalledException();
          }
          alreadyCalled = true;
        }

        originalCallback.run(parameter);
      }
    };
  }

  /**
   * Exception thrown when a one-time callback is called more than once.
   */
  public static final class AlreadyCalledException extends RuntimeException {
    private static final long serialVersionUID = 5469741279507848266L;

    public AlreadyCalledException() {
      super("This RpcCallback was already called and cannot be called " +
            "multiple times.");
    }
  }
}
