/*
 *
 * Copyright 2014, Google Inc.
 * All rights reserved.
 *
 * 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.
 *
 */

#include "src/core/channel/metadata_buffer.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>

#include <string.h>

#define INITIAL_ELEM_CAP 8

/* One queued call; we track offsets to string data in a shared buffer to
   reduce allocations. See grpc_metadata_buffer_impl for the memory use
   strategy */
typedef struct {
  grpc_mdelem *md;
  void (*cb)(void *user_data, grpc_op_error error);
  void *user_data;
  gpr_uint32 flags;
} qelem;

/* Memory layout:

  grpc_metadata_buffer_impl
  followed by an array of qelem  */
struct grpc_metadata_buffer_impl {
  /* number of elements in q */
  size_t elems;
  /* capacity of q */
  size_t elem_cap;
};

#define ELEMS(buffer) ((qelem *)((buffer) + 1))

void grpc_metadata_buffer_init(grpc_metadata_buffer *buffer) {
  /* start buffer as NULL, indicating no elements */
  *buffer = NULL;
}

void grpc_metadata_buffer_destroy(grpc_metadata_buffer *buffer,
                                  grpc_op_error error) {
  size_t i;
  qelem *qe;
  if (*buffer) {
    for (i = 0; i < (*buffer)->elems; i++) {
      qe = &ELEMS(*buffer)[i];
      grpc_mdelem_unref(qe->md);
      qe->cb(qe->user_data, error);
    }
    gpr_free(*buffer);
  }
}

void grpc_metadata_buffer_queue(grpc_metadata_buffer *buffer,
                                grpc_call_op *op) {
  grpc_metadata_buffer_impl *impl = *buffer;
  qelem *qe;
  size_t bytes;

  GPR_ASSERT(op->type == GRPC_SEND_METADATA || op->type == GRPC_RECV_METADATA);

  if (!impl) {
    /* this is the first element: allocate enough space to hold the
       header object and the initial element capacity of qelems */
    bytes =
        sizeof(grpc_metadata_buffer_impl) + INITIAL_ELEM_CAP * sizeof(qelem);
    impl = gpr_malloc(bytes);
    /* initialize the header object */
    impl->elems = 0;
    impl->elem_cap = INITIAL_ELEM_CAP;
  } else if (impl->elems == impl->elem_cap) {
    /* more qelems than what we can deal with: grow by doubling size */
    impl->elem_cap *= 2;
    bytes = sizeof(grpc_metadata_buffer_impl) + impl->elem_cap * sizeof(qelem);
    impl = gpr_realloc(impl, bytes);
  }

  /* append an element to the queue */
  qe = &ELEMS(impl)[impl->elems];
  impl->elems++;

  qe->md = op->data.metadata;
  qe->cb = op->done_cb;
  qe->user_data = op->user_data;
  qe->flags = op->flags;

  /* header object may have changed location: store it back */
  *buffer = impl;
}

void grpc_metadata_buffer_flush(grpc_metadata_buffer *buffer,
                                grpc_call_element *elem) {
  grpc_metadata_buffer_impl *impl = *buffer;
  grpc_call_op op;
  qelem *qe;
  size_t i;

  if (!impl) {
    /* nothing to send */
    return;
  }

  /* construct call_op's, and push them down the stack */
  op.type = GRPC_SEND_METADATA;
  op.dir = GRPC_CALL_DOWN;
  for (i = 0; i < impl->elems; i++) {
    qe = &ELEMS(impl)[i];
    op.done_cb = qe->cb;
    op.user_data = qe->user_data;
    op.flags = qe->flags;
    op.data.metadata = qe->md;
    grpc_call_next_op(elem, &op);
  }

  /* free data structures and reset to NULL: we can only flush once */
  gpr_free(impl);
  *buffer = NULL;
}

size_t grpc_metadata_buffer_count(const grpc_metadata_buffer *buffer) {
  return *buffer ? (*buffer)->elems : 0;
}

typedef struct { grpc_metadata_buffer_impl *impl; } elems_hdr;

grpc_metadata *grpc_metadata_buffer_extract_elements(
    grpc_metadata_buffer *buffer) {
  grpc_metadata_buffer_impl *impl;
  elems_hdr *hdr;
  qelem *src;
  grpc_metadata *out;
  size_t i;

  impl = *buffer;

  if (!impl) {
    return NULL;
  }

  hdr = gpr_malloc(sizeof(elems_hdr) + impl->elems * sizeof(grpc_metadata));
  src = ELEMS(impl);
  out = (grpc_metadata *)(hdr + 1);

  hdr->impl = impl;
  for (i = 0; i < impl->elems; i++) {
    out[i].key = (char *)grpc_mdstr_as_c_string(src[i].md->key);
    out[i].value = (char *)grpc_mdstr_as_c_string(src[i].md->value);
    out[i].value_length = GPR_SLICE_LENGTH(src[i].md->value->slice);
  }

  /* clear out buffer (it's not possible to extract elements twice */
  *buffer = NULL;

  return out;
}

void grpc_metadata_buffer_cleanup_elements(void *elements,
                                           grpc_op_error error) {
  elems_hdr *hdr = ((elems_hdr *)elements) - 1;

  if (!elements) {
    return;
  }

  grpc_metadata_buffer_destroy(&hdr->impl, error);
  gpr_free(hdr);
}
