/*
 *
 * Copyright 2015, 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/lib/security/credentials/credentials.h"

#include <grpc/support/alloc.h>

#include <string.h>

#include "src/core/lib/slice/slice_internal.h"

static void store_ensure_capacity(grpc_credentials_md_store *store) {
  if (store->num_entries == store->allocated) {
    store->allocated = (store->allocated == 0) ? 1 : store->allocated * 2;
    store->entries = gpr_realloc(
        store->entries, store->allocated * sizeof(grpc_credentials_md));
  }
}

grpc_credentials_md_store *grpc_credentials_md_store_create(
    size_t initial_capacity) {
  grpc_credentials_md_store *store =
      gpr_zalloc(sizeof(grpc_credentials_md_store));
  if (initial_capacity > 0) {
    store->entries = gpr_malloc(initial_capacity * sizeof(grpc_credentials_md));
    store->allocated = initial_capacity;
  }
  gpr_ref_init(&store->refcount, 1);
  return store;
}

void grpc_credentials_md_store_add(grpc_credentials_md_store *store,
                                   grpc_slice key, grpc_slice value) {
  if (store == NULL) return;
  store_ensure_capacity(store);
  store->entries[store->num_entries].key = grpc_slice_ref_internal(key);
  store->entries[store->num_entries].value = grpc_slice_ref_internal(value);
  store->num_entries++;
}

void grpc_credentials_md_store_add_cstrings(grpc_credentials_md_store *store,
                                            const char *key,
                                            const char *value) {
  if (store == NULL) return;
  store_ensure_capacity(store);
  store->entries[store->num_entries].key = grpc_slice_from_copied_string(key);
  store->entries[store->num_entries].value =
      grpc_slice_from_copied_string(value);
  store->num_entries++;
}

grpc_credentials_md_store *grpc_credentials_md_store_ref(
    grpc_credentials_md_store *store) {
  if (store == NULL) return NULL;
  gpr_ref(&store->refcount);
  return store;
}

void grpc_credentials_md_store_unref(grpc_exec_ctx *exec_ctx,
                                     grpc_credentials_md_store *store) {
  if (store == NULL) return;
  if (gpr_unref(&store->refcount)) {
    if (store->entries != NULL) {
      size_t i;
      for (i = 0; i < store->num_entries; i++) {
        grpc_slice_unref_internal(exec_ctx, store->entries[i].key);
        grpc_slice_unref_internal(exec_ctx, store->entries[i].value);
      }
      gpr_free(store->entries);
    }
    gpr_free(store);
  }
}
