/*
 *
 * 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.
 *
 */

/**
 * class Call
 * @see https://github.com/grpc/grpc/tree/master/src/php/ext/grpc/call.c
 */

#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);
    efree(str_val);
  }
  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 = NULL;
  int cancelled;
  grpc_call_error error;

  zend_string* zmessage = NULL;

  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;
  }

  // c-core may call rand(). If we don't call srand() here, all the
  // random numbers being returned would be the same.
  gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
  srand(now.tv_nsec);

  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()

  grpc_call *wrapped = call->wrapped;
  error = grpc_call_start_batch(wrapped, ops, op_num, 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, wrapped,
                              gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
  zval *recv_md;
  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:
      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);
      PHP_GRPC_DELREF(array);
      break;
    case GRPC_OP_RECV_MESSAGE:
      zmessage = byte_buffer_to_zend_string(message);

      if (zmessage == NULL) {
        add_property_null(result, "message");
      } else {
        zval zmessage_val;
        ZVAL_NEW_STR(&zmessage_val, zmessage);
        add_property_zval(result, "message", &zmessage_val);
        zval_ptr_dtor(&zmessage_val);
      }
      break;
    case GRPC_OP_RECV_STATUS_ON_CLIENT:
      PHP_GRPC_MAKE_STD_ZVAL(recv_status);
      object_init(recv_status);
      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);
      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);
      zval_ptr_dtor(recv_status);
      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);
    }
  }
  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);
  zval property_channel_default_value;
  ZVAL_NULL(&property_channel_default_value);
  zend_string *property_channel_name = zend_string_init("channel", sizeof("channel") - 1, 1);
  zend_declare_property_ex(grpc_ce_call, property_channel_name, &property_channel_default_value, ZEND_ACC_PROTECTED, NULL);
  zend_string_release(property_channel_name);
  PHP_GRPC_INIT_HANDLER(wrapped_grpc_call, call_ce_handlers);
}
