/*
 *
 * Copyright 2015-2016, 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/transport/chttp2/stream_map.h"
#include <grpc/support/log.h>
#include "test/core/util/test_config.h"

#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)

/* test creation & destruction */
static void test_no_op(void) {
  grpc_chttp2_stream_map map;

  LOG_TEST("test_no_op");

  grpc_chttp2_stream_map_init(&map, 8);
  grpc_chttp2_stream_map_destroy(&map);
}

/* test lookup on an empty map */
static void test_empty_find(void) {
  grpc_chttp2_stream_map map;

  LOG_TEST("test_empty_find");

  grpc_chttp2_stream_map_init(&map, 8);
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 39128));
  grpc_chttp2_stream_map_destroy(&map);
}

/* test it's safe to delete twice */
static void test_double_deletion(void) {
  grpc_chttp2_stream_map map;

  LOG_TEST("test_double_deletion");

  grpc_chttp2_stream_map_init(&map, 8);
  GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map));
  grpc_chttp2_stream_map_add(&map, 1, (void *)1);
  GPR_ASSERT((void *)1 == grpc_chttp2_stream_map_find(&map, 1));
  GPR_ASSERT(1 == grpc_chttp2_stream_map_size(&map));
  GPR_ASSERT((void *)1 == grpc_chttp2_stream_map_delete(&map, 1));
  GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map));
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 1));
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_delete(&map, 1));
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 1));
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_delete(&map, 1));
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 1));
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_delete(&map, 1));
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 1));
  grpc_chttp2_stream_map_destroy(&map);
}

/* test add & lookup */
static void test_basic_add_find(uint32_t n) {
  grpc_chttp2_stream_map map;
  uint32_t i;
  size_t got;

  LOG_TEST("test_basic_add_find");
  gpr_log(GPR_INFO, "n = %d", n);

  grpc_chttp2_stream_map_init(&map, 8);
  GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map));
  for (i = 1; i <= n; i++) {
    grpc_chttp2_stream_map_add(&map, i, (void *)(uintptr_t)i);
  }
  GPR_ASSERT(n == grpc_chttp2_stream_map_size(&map));
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 0));
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, n + 1));
  for (i = 1; i <= n; i++) {
    got = (uintptr_t)grpc_chttp2_stream_map_find(&map, i);
    GPR_ASSERT(i == got);
  }
  grpc_chttp2_stream_map_destroy(&map);
}

/* verify that for_each gets the right values during test_delete_evens_XXX */
static void verify_for_each(void *user_data, uint32_t stream_id, void *ptr) {
  uint32_t *for_each_check = user_data;
  GPR_ASSERT(ptr);
  GPR_ASSERT(*for_each_check == stream_id);
  *for_each_check += 2;
}

static void check_delete_evens(grpc_chttp2_stream_map *map, uint32_t n) {
  uint32_t for_each_check = 1;
  uint32_t i;
  size_t got;

  GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(map, 0));
  GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(map, n + 1));
  for (i = 1; i <= n; i++) {
    if (i & 1) {
      got = (uintptr_t)grpc_chttp2_stream_map_find(map, i);
      GPR_ASSERT(i == got);
    } else {
      GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(map, i));
    }
  }

  grpc_chttp2_stream_map_for_each(map, verify_for_each, &for_each_check);
  if (n & 1) {
    GPR_ASSERT(for_each_check == n + 2);
  } else {
    GPR_ASSERT(for_each_check == n + 1);
  }
}

/* add a bunch of keys, delete the even ones, and make sure the map is
   consistent */
static void test_delete_evens_sweep(uint32_t n) {
  grpc_chttp2_stream_map map;
  uint32_t i;

  LOG_TEST("test_delete_evens_sweep");
  gpr_log(GPR_INFO, "n = %d", n);

  grpc_chttp2_stream_map_init(&map, 8);
  for (i = 1; i <= n; i++) {
    grpc_chttp2_stream_map_add(&map, i, (void *)(uintptr_t)i);
  }
  for (i = 1; i <= n; i++) {
    if ((i & 1) == 0) {
      GPR_ASSERT((void *)(uintptr_t)i ==
                 grpc_chttp2_stream_map_delete(&map, i));
    }
  }
  check_delete_evens(&map, n);
  grpc_chttp2_stream_map_destroy(&map);
}

/* add a bunch of keys, delete the even ones immediately, and make sure the map
   is consistent */
static void test_delete_evens_incremental(uint32_t n) {
  grpc_chttp2_stream_map map;
  uint32_t i;

  LOG_TEST("test_delete_evens_incremental");
  gpr_log(GPR_INFO, "n = %d", n);

  grpc_chttp2_stream_map_init(&map, 8);
  for (i = 1; i <= n; i++) {
    grpc_chttp2_stream_map_add(&map, i, (void *)(uintptr_t)i);
    if ((i & 1) == 0) {
      grpc_chttp2_stream_map_delete(&map, i);
    }
  }
  check_delete_evens(&map, n);
  grpc_chttp2_stream_map_destroy(&map);
}

/* add a bunch of keys, delete old ones after some time, ensure the
   backing array does not grow */
static void test_periodic_compaction(uint32_t n) {
  grpc_chttp2_stream_map map;
  uint32_t i;
  uint32_t del;

  LOG_TEST("test_periodic_compaction");
  gpr_log(GPR_INFO, "n = %d", n);

  grpc_chttp2_stream_map_init(&map, 16);
  GPR_ASSERT(map.capacity == 16);
  for (i = 1; i <= n; i++) {
    grpc_chttp2_stream_map_add(&map, i, (void *)(uintptr_t)i);
    if (i > 8) {
      del = i - 8;
      GPR_ASSERT((void *)(uintptr_t)del ==
                 grpc_chttp2_stream_map_delete(&map, del));
    }
  }
  GPR_ASSERT(map.capacity == 16);
  grpc_chttp2_stream_map_destroy(&map);
}

int main(int argc, char **argv) {
  uint32_t n = 1;
  uint32_t prev = 1;
  uint32_t tmp;

  grpc_test_init(argc, argv);

  test_no_op();
  test_empty_find();
  test_double_deletion();

  while (n < 100000) {
    test_basic_add_find(n);
    test_delete_evens_sweep(n);
    test_delete_evens_incremental(n);
    test_periodic_compaction(n);

    tmp = n;
    n += prev;
    prev = tmp;
  }

  return 0;
}
