/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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.
 *
 */

#include "call.h"

#include <ext/spl/spl_exceptions.h>
#include <zend_exceptions.h>

#include <grpc/support/alloc.h>

#include "call_credentials.h"
#include "completion_queue.h"
#include "timeval.h"
#include "channel.h"
#include "byte_buffer.h"

zend_class_entry *grpc_ce_call;
PHP_GRPC_DECLARE_OBJECT_HANDLER(call_ce_handlers)

/* Frees and destroys an instance of wrapped_grpc_call */
PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_call)
  if (p->owned && p->wrapped != NULL) {
    grpc_call_unref(p->wrapped);
  }
PHP_GRPC_FREE_WRAPPED_FUNC_END()

/* Initializes an instance of wrapped_grpc_call to be associated with an
 * object of a class specified by class_type */
php_grpc_zend_object create_wrapped_grpc_call(zend_class_entry *class_type
                                              TSRMLS_DC) {
  PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_call);
  zend_object_std_init(&intern->std, class_type TSRMLS_CC);
  object_properties_init(&intern->std, class_type);
  PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_call, call_ce_handlers);
}

/* Creates and returns a PHP array object with the data in a
 * grpc_metadata_array. Returns NULL on failure */
zval *grpc_parse_metadata_array(grpc_metadata_array
                                *metadata_array TSRMLS_DC) {
  int count = metadata_array->count;
  grpc_metadata *elements = metadata_array->metadata;
  zval *array;
  PHP_GRPC_MAKE_STD_ZVAL(array);
  array_init(array);
  int i;
  HashTable *array_hash;
  zval *inner_array;
  char *str_key;
  char *str_val;
  size_t key_len;
  zval *data = NULL;

  array_hash = Z_ARRVAL_P(array);
  grpc_metadata *elem;
  for (i = 0; i < count; i++) {
    elem = &elements[i];
    key_len = GRPC_SLICE_LENGTH(elem->key);
    str_key = ecalloc(key_len + 1, sizeof(char));
    memcpy(str_key, GRPC_SLICE_START_PTR(elem->key), key_len);
    str_val = ecalloc(GRPC_SLICE_LENGTH(elem->value) + 1, sizeof(char));
    memcpy(str_val, GRPC_SLICE_START_PTR(elem->value),
           GRPC_SLICE_LENGTH(elem->value));
    if (php_grpc_zend_hash_find(array_hash, str_key, key_len, (void **)&data)
        == SUCCESS) {
      if (Z_TYPE_P(data) != IS_ARRAY) {
        zend_throw_exception(zend_exception_get_default(TSRMLS_C),
                             "Metadata hash somehow contains wrong types.",
                             1 TSRMLS_CC);
        efree(str_key);
        efree(str_val);
        PHP_GRPC_FREE_STD_ZVAL(array);
        return NULL;
      }
      php_grpc_add_next_index_stringl(data, str_val,
                                      GRPC_SLICE_LENGTH(elem->value),
                                      false);
    } else {
      PHP_GRPC_MAKE_STD_ZVAL(inner_array);
      array_init(inner_array);
      php_grpc_add_next_index_stringl(inner_array, str_val,
                                      GRPC_SLICE_LENGTH(elem->value), false);
      add_assoc_zval(array, str_key, inner_array);
      PHP_GRPC_FREE_STD_ZVAL(inner_array);
    }
    efree(str_key);
#if PHP_MAJOR_VERSION >= 7
    efree(str_val);
#endif
  }
  return array;
}

/* Populates a grpc_metadata_array with the data in a PHP array object.
   Returns true on success and false on failure */
bool create_metadata_array(zval *array, grpc_metadata_array *metadata) {
  HashTable *array_hash;
  HashTable *inner_array_hash;
  zval *value;
  zval *inner_array;
  grpc_metadata_array_init(metadata);
  metadata->count = 0;
  metadata->metadata = NULL;
  if (Z_TYPE_P(array) != IS_ARRAY) {
    return false;
  }
  array_hash = Z_ARRVAL_P(array);

  char *key;
  int key_type;
  PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(array_hash, key, key_type,
                                          inner_array)
    if (key_type != HASH_KEY_IS_STRING || key == NULL) {
      return false;
    }
    if (Z_TYPE_P(inner_array) != IS_ARRAY) {
      return false;
    }
    inner_array_hash = Z_ARRVAL_P(inner_array);
    metadata->capacity += zend_hash_num_elements(inner_array_hash);
  PHP_GRPC_HASH_FOREACH_END()

  metadata->metadata = gpr_malloc(metadata->capacity * sizeof(grpc_metadata));

  char *key1 = NULL;
  int key_type1;
  PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(array_hash, key1, key_type1,
                                          inner_array)
    if (key_type1 != HASH_KEY_IS_STRING) {
      return false;
    }
    if (!grpc_header_key_is_legal(grpc_slice_from_static_string(key1))) {
      return false;
    }
    inner_array_hash = Z_ARRVAL_P(inner_array);
    PHP_GRPC_HASH_FOREACH_VAL_START(inner_array_hash, value)
      if (Z_TYPE_P(value) != IS_STRING) {
        return false;
      }
      metadata->metadata[metadata->count].key =
        grpc_slice_from_copied_string(key1);
      metadata->metadata[metadata->count].value =
        grpc_slice_from_copied_buffer(Z_STRVAL_P(value), Z_STRLEN_P(value));
      metadata->count += 1;
    PHP_GRPC_HASH_FOREACH_END()
  PHP_GRPC_HASH_FOREACH_END()
  return true;
}

void grpc_php_metadata_array_destroy_including_entries(
    grpc_metadata_array* array) {
  size_t i;
  if (array->metadata) {
    for (i = 0; i < array->count; i++) {
      grpc_slice_unref(array->metadata[i].key);
      grpc_slice_unref(array->metadata[i].value);
    }
  }
  grpc_metadata_array_destroy(array);
}

/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the
   struct should be destroyed at the end of the object's lifecycle */
zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC) {
  zval *call_object;
  PHP_GRPC_MAKE_STD_ZVAL(call_object);
  object_init_ex(call_object, grpc_ce_call);
  wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call,
                                                        call_object);
  call->wrapped = wrapped;
  call->owned = owned;
  return call_object;
}

/**
 * Constructs a new instance of the Call class.
 * @param Channel $channel_obj The channel to associate the call with.
 *                             Must not be closed.
 * @param string $method The method to call
 * @param Timeval $deadline_obj The deadline for completing the call
 * @param string $host_override The host is set by user (optional)
 */
PHP_METHOD(Call, __construct) {
  zval *channel_obj;
  char *method;
  php_grpc_int method_len;
  zval *deadline_obj;
  char *host_override = NULL;
  php_grpc_int host_override_len = 0;
  wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call,
                                                        getThis());

  /* "OsO|s" == 1 Object, 1 string, 1 Object, 1 optional string */
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO|s", &channel_obj,
                            grpc_ce_channel, &method, &method_len,
                            &deadline_obj, grpc_ce_timeval, &host_override,
                            &host_override_len) == FAILURE) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "Call expects a Channel, a String, a Timeval and "
                         "an optional String", 1 TSRMLS_CC);
    return;
  }
  wrapped_grpc_channel *channel =
    PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, channel_obj);
  if (channel->wrapper == NULL) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "Call cannot be constructed from a closed Channel",
                         1 TSRMLS_CC);
    return;
  }
  gpr_mu_lock(&channel->wrapper->mu);
  if (channel->wrapper == NULL || channel->wrapper->wrapped == NULL) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "Call cannot be constructed from a closed Channel",
                         1 TSRMLS_CC);
    gpr_mu_unlock(&channel->wrapper->mu);
    return;
  }
  add_property_zval(getThis(), "channel", channel_obj);
  wrapped_grpc_timeval *deadline =
    PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_timeval, deadline_obj);
  grpc_slice method_slice = grpc_slice_from_copied_string(method);
  grpc_slice host_slice = host_override != NULL ?
      grpc_slice_from_copied_string(host_override) : grpc_empty_slice();
  call->wrapped =
    grpc_channel_create_call(channel->wrapper->wrapped, NULL,
                             GRPC_PROPAGATE_DEFAULTS,
                             completion_queue, method_slice,
                             host_override != NULL ? &host_slice : NULL,
                             deadline->wrapped, NULL);
  grpc_slice_unref(method_slice);
  grpc_slice_unref(host_slice);
  call->owned = true;
  call->channel = channel;
  gpr_mu_unlock(&channel->wrapper->mu);
}

/**
 * Start a batch of RPC actions.
 * @param array $array Array of actions to take
 * @return object Object with results of all actions
 */
PHP_METHOD(Call, startBatch) {
  zval *result;
  PHP_GRPC_MAKE_STD_ZVAL(result);
  object_init(result);
  php_grpc_ulong index;
  zval *recv_status;
  zval *value;
  zval *inner_value;
  zval *message_value;
  zval *message_flags;
  wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call,
                                                        getThis());
  if (call->channel) {
    // startBatch in gRPC PHP server doesn't have channel in it.
    if (call->channel->wrapper == NULL ||
        call->channel->wrapper->wrapped == NULL) {
      zend_throw_exception(spl_ce_RuntimeException,
                           "startBatch Error. Channel is closed",
                           1 TSRMLS_CC);
    }
  }
  
  grpc_op ops[8];
  size_t op_num = 0;
  zval *array;
  HashTable *array_hash;
  HashTable *status_hash;
  HashTable *message_hash;

  grpc_metadata_array metadata;
  grpc_metadata_array trailing_metadata;
  grpc_metadata_array recv_metadata;
  grpc_metadata_array recv_trailing_metadata;
  grpc_status_code status;
  grpc_slice recv_status_details = grpc_empty_slice();
  grpc_slice send_status_details = grpc_empty_slice();
  grpc_byte_buffer *message;
  int cancelled;
  grpc_call_error error;

  #if PHP_MAJOR_VERSION < 7
  char *message_str;
  size_t message_len;
  #else
  zend_string* zmessage = NULL;
  #endif // PHP_MAJOR_VERSION < 7

  grpc_metadata_array_init(&metadata);
  grpc_metadata_array_init(&trailing_metadata);
  grpc_metadata_array_init(&recv_metadata);
  grpc_metadata_array_init(&recv_trailing_metadata);
  memset(ops, 0, sizeof(ops));
  
  /* "a" == 1 array */
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) ==
      FAILURE) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "start_batch expects an array", 1 TSRMLS_CC);
    goto cleanup;
  }

  array_hash = Z_ARRVAL_P(array);

  char *key = NULL;
  int key_type;
  PHP_GRPC_HASH_FOREACH_LONG_KEY_VAL_START(array_hash, key, key_type, index,
                                           value)
    if (key_type != HASH_KEY_IS_LONG || key != NULL) {
      zend_throw_exception(spl_ce_InvalidArgumentException,
                           "batch keys must be integers", 1 TSRMLS_CC);
      goto cleanup;
    }

    ops[op_num].op = (grpc_op_type)index;
    ops[op_num].flags = 0;
    ops[op_num].reserved = NULL;

    switch(index) {
    case GRPC_OP_SEND_INITIAL_METADATA:
      if (!create_metadata_array(value, &metadata)) {
        zend_throw_exception(spl_ce_InvalidArgumentException,
                             "Bad metadata value given", 1 TSRMLS_CC);
        goto cleanup;
      }
      ops[op_num].data.send_initial_metadata.count = metadata.count;
      ops[op_num].data.send_initial_metadata.metadata = metadata.metadata;
      break;
    case GRPC_OP_SEND_MESSAGE:
      if (Z_TYPE_P(value) != IS_ARRAY) {
        zend_throw_exception(spl_ce_InvalidArgumentException,
                             "Expected an array for send message",
                             1 TSRMLS_CC);
        goto cleanup;
      }
      message_hash = Z_ARRVAL_P(value);
      if (php_grpc_zend_hash_find(message_hash, "flags", sizeof("flags"),
                         (void **)&message_flags) == SUCCESS) {
        if (Z_TYPE_P(message_flags) != IS_LONG) {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Expected an int for message flags",
                               1 TSRMLS_CC);
        }
        ops[op_num].flags = Z_LVAL_P(message_flags) & GRPC_WRITE_USED_MASK;
      }
      if (php_grpc_zend_hash_find(message_hash, "message", sizeof("message"),
                         (void **)&message_value) != SUCCESS ||
          Z_TYPE_P(message_value) != IS_STRING) {
        zend_throw_exception(spl_ce_InvalidArgumentException,
                             "Expected a string for send message",
                             1 TSRMLS_CC);
        goto cleanup;
      }
      ops[op_num].data.send_message.send_message =
          string_to_byte_buffer(Z_STRVAL_P(message_value),
                                Z_STRLEN_P(message_value));
      break;
    case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
      break;
    case GRPC_OP_SEND_STATUS_FROM_SERVER:
      status_hash = Z_ARRVAL_P(value);
      if (php_grpc_zend_hash_find(status_hash, "metadata", sizeof("metadata"),
                         (void **)&inner_value) == SUCCESS) {
        if (!create_metadata_array(inner_value, &trailing_metadata)) {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Bad trailing metadata value given",
                               1 TSRMLS_CC);
          goto cleanup;
        }
        ops[op_num].data.send_status_from_server.trailing_metadata =
            trailing_metadata.metadata;
        ops[op_num].data.send_status_from_server.trailing_metadata_count =
            trailing_metadata.count;
      }
      if (php_grpc_zend_hash_find(status_hash, "code", sizeof("code"),
                         (void**)&inner_value) == SUCCESS) {
        if (Z_TYPE_P(inner_value) != IS_LONG) {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Status code must be an integer",
                               1 TSRMLS_CC);
          goto cleanup;
        }
        ops[op_num].data.send_status_from_server.status =
            Z_LVAL_P(inner_value);
      } else {
        zend_throw_exception(spl_ce_InvalidArgumentException,
                             "Integer status code is required",
                             1 TSRMLS_CC);
        goto cleanup;
      }
      if (php_grpc_zend_hash_find(status_hash, "details", sizeof("details"),
                         (void**)&inner_value) == SUCCESS) {
        if (Z_TYPE_P(inner_value) != IS_STRING) {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Status details must be a string",
                               1 TSRMLS_CC);
          goto cleanup;
        }
        send_status_details = grpc_slice_from_copied_string(
          Z_STRVAL_P(inner_value));
        ops[op_num].data.send_status_from_server.status_details =
          &send_status_details;
      } else {
        zend_throw_exception(spl_ce_InvalidArgumentException,
                             "String status details is required",
                             1 TSRMLS_CC);
        goto cleanup;
      }
      break;
    case GRPC_OP_RECV_INITIAL_METADATA:
      ops[op_num].data.recv_initial_metadata.recv_initial_metadata =
          &recv_metadata;
      break;
    case GRPC_OP_RECV_MESSAGE:
      ops[op_num].data.recv_message.recv_message = &message;
      break;
    case GRPC_OP_RECV_STATUS_ON_CLIENT:
      ops[op_num].data.recv_status_on_client.trailing_metadata =
          &recv_trailing_metadata;
      ops[op_num].data.recv_status_on_client.status = &status;
      ops[op_num].data.recv_status_on_client.status_details =
          &recv_status_details;
      break;
    case GRPC_OP_RECV_CLOSE_ON_SERVER:
      ops[op_num].data.recv_close_on_server.cancelled = &cancelled;
      break;
    default:
      zend_throw_exception(spl_ce_InvalidArgumentException,
                           "Unrecognized key in batch", 1 TSRMLS_CC);
      goto cleanup;
    }
    op_num++;
  PHP_GRPC_HASH_FOREACH_END()

  error = grpc_call_start_batch(call->wrapped, ops, op_num, call->wrapped,
                                NULL);
  if (error != GRPC_CALL_OK) {
    zend_throw_exception(spl_ce_LogicException,
                         "start_batch was called incorrectly",
                         (long)error TSRMLS_CC);
    goto cleanup;
  }
  grpc_completion_queue_pluck(completion_queue, call->wrapped,
                              gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
#if PHP_MAJOR_VERSION >= 7
  zval *recv_md;
#endif
  for (int i = 0; i < op_num; i++) {
    switch(ops[i].op) {
    case GRPC_OP_SEND_INITIAL_METADATA:
      add_property_bool(result, "send_metadata", true);
      break;
    case GRPC_OP_SEND_MESSAGE:
      add_property_bool(result, "send_message", true);
      break;
    case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
      add_property_bool(result, "send_close", true);
      break;
    case GRPC_OP_SEND_STATUS_FROM_SERVER:
      add_property_bool(result, "send_status", true);
      break;
    case GRPC_OP_RECV_INITIAL_METADATA:
#if PHP_MAJOR_VERSION < 7
      array = grpc_parse_metadata_array(&recv_metadata TSRMLS_CC);
      add_property_zval(result, "metadata", array);
#else
      recv_md = grpc_parse_metadata_array(&recv_metadata);
      add_property_zval(result, "metadata", recv_md);
      zval_ptr_dtor(recv_md);
      PHP_GRPC_FREE_STD_ZVAL(recv_md);
#endif
      PHP_GRPC_DELREF(array);
      break;
    case GRPC_OP_RECV_MESSAGE:
#if PHP_MAJOR_VERSION < 7
      byte_buffer_to_string(message, &message_str, &message_len);
#else
      zmessage = byte_buffer_to_zend_string(message);
#endif // PHP_MAJOR_VERSION < 7

#if PHP_MAJOR_VERSION < 7
      if (message_str == NULL) {
#else
      if (zmessage == NULL) {
#endif // PHP_MAJOR_VERSION < 7
        add_property_null(result, "message");
      } else {
#if PHP_MAJOR_VERSION < 7
        php_grpc_add_property_stringl(result, "message", message_str,
                                      message_len, false);
#else
        zval zmessage_val;
        ZVAL_NEW_STR(&zmessage_val, zmessage);
        add_property_zval(result, "message", &zmessage_val);
        zval_ptr_dtor(&zmessage_val);
#endif // PHP_MAJOR_VERSION < 7
      }
      break;
    case GRPC_OP_RECV_STATUS_ON_CLIENT:
      PHP_GRPC_MAKE_STD_ZVAL(recv_status);
      object_init(recv_status);
#if PHP_MAJOR_VERSION < 7
      array = grpc_parse_metadata_array(&recv_trailing_metadata TSRMLS_CC);
      add_property_zval(recv_status, "metadata", array);
#else
      recv_md = grpc_parse_metadata_array(&recv_trailing_metadata);
      add_property_zval(recv_status, "metadata", recv_md);
      zval_ptr_dtor(recv_md);
      PHP_GRPC_FREE_STD_ZVAL(recv_md);
#endif
      PHP_GRPC_DELREF(array);
      add_property_long(recv_status, "code", status);
      char *status_details_text = grpc_slice_to_c_string(recv_status_details);
      php_grpc_add_property_string(recv_status, "details", status_details_text,
                                   true);
      gpr_free(status_details_text);
      add_property_zval(result, "status", recv_status);
#if PHP_MAJOR_VERSION >= 7
      zval_ptr_dtor(recv_status);
#endif
      PHP_GRPC_DELREF(recv_status);
      PHP_GRPC_FREE_STD_ZVAL(recv_status);
      break;
    case GRPC_OP_RECV_CLOSE_ON_SERVER:
      add_property_bool(result, "cancelled", cancelled);
      break;
    default:
      break;
    }
  }

cleanup:
  grpc_php_metadata_array_destroy_including_entries(&metadata);
  grpc_php_metadata_array_destroy_including_entries(&trailing_metadata);
  grpc_metadata_array_destroy(&recv_metadata);
  grpc_metadata_array_destroy(&recv_trailing_metadata);
  grpc_slice_unref(recv_status_details);
  grpc_slice_unref(send_status_details);
  for (int i = 0; i < op_num; i++) {
    if (ops[i].op == GRPC_OP_SEND_MESSAGE) {
      grpc_byte_buffer_destroy(ops[i].data.send_message.send_message);
    }
    if (ops[i].op == GRPC_OP_RECV_MESSAGE) {
      grpc_byte_buffer_destroy(message);
      #if PHP_MAJOR_VERSION < 7
      PHP_GRPC_FREE_STD_ZVAL(message_str);
      #endif // PHP_MAJOR_VERSION < 7
    }
  }
  RETURN_DESTROY_ZVAL(result);
}

/**
 * Get the endpoint this call/stream is connected to
 * @return string The URI of the endpoint
 */
PHP_METHOD(Call, getPeer) {
  wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call,
                                                        getThis());
  char *peer = grpc_call_get_peer(call->wrapped);
  PHP_GRPC_RETVAL_STRING(peer, 1);
  gpr_free(peer);
}

/**
 * Cancel the call. This will cause the call to end with STATUS_CANCELLED
 * if it has not already ended with another status.
 * @return void
 */
PHP_METHOD(Call, cancel) {
  wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call,
                                                        getThis());
  grpc_call_cancel(call->wrapped, NULL);
}

/**
 * Set the CallCredentials for this call.
 * @param CallCredentials $creds_obj The CallCredentials object
 * @return int The error code
 */
PHP_METHOD(Call, setCredentials) {
  zval *creds_obj;

  /* "O" == 1 Object */
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &creds_obj,
                            grpc_ce_call_credentials) == FAILURE) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "setCredentials expects 1 CallCredentials",
                         1 TSRMLS_CC);
    return;
  }

  wrapped_grpc_call_credentials *creds =
    PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call_credentials, creds_obj);
  wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call,
                                                        getThis());

  grpc_call_error error = GRPC_CALL_ERROR;
  error = grpc_call_set_credentials(call->wrapped, creds->wrapped);
  RETURN_LONG(error);
}

ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 3)
  ZEND_ARG_INFO(0, channel)
  ZEND_ARG_INFO(0, method)
  ZEND_ARG_INFO(0, deadline)
  ZEND_ARG_INFO(0, host_override)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_startBatch, 0, 0, 1)
  ZEND_ARG_INFO(0, ops)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_getPeer, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_cancel, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_setCredentials, 0, 0, 1)
  ZEND_ARG_INFO(0, credentials)
ZEND_END_ARG_INFO()

static zend_function_entry call_methods[] = {
  PHP_ME(Call, __construct, arginfo_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
  PHP_ME(Call, startBatch, arginfo_startBatch, ZEND_ACC_PUBLIC)
  PHP_ME(Call, getPeer, arginfo_getPeer, ZEND_ACC_PUBLIC)
  PHP_ME(Call, cancel, arginfo_cancel, ZEND_ACC_PUBLIC)
  PHP_ME(Call, setCredentials, arginfo_setCredentials, ZEND_ACC_PUBLIC)
  PHP_FE_END
};

void grpc_init_call(TSRMLS_D) {
  zend_class_entry ce;
  INIT_CLASS_ENTRY(ce, "Grpc\\Call", call_methods);
  ce.create_object = create_wrapped_grpc_call;
  grpc_ce_call = zend_register_internal_class(&ce TSRMLS_CC);
  PHP_GRPC_INIT_HANDLER(wrapped_grpc_call, call_ce_handlers);
}
