/*
 * Copyright (c) 2021 EMnify.
 *
 * 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 <vlib/vlib.h>
#include <vppinfra/time.h>
#include <vppinfra/cache.h>
#include <vppinfra/error.h>

#include <vlib/counter.h>
#include <vlib/stats/stats.h>

enum
{
  type_simple = 0,
  type_combined,
};

enum
{
  test_expand = 0,
};

/*
 * Return the stats segment epoch value.
 */
static uint64_t
get_stats_epoch ()
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  return sm->shared_header->epoch;
}

/* number of times to repeat the counter expand tests */
#define EXPAND_TEST_ROUNDS 3

/*
 * Let a simple counter vector grow and verify that
 * the stats epoch is increased only when the vector
 * is expanded.
 */
static clib_error_t *
test_simple_counter_expand (vlib_main_t *vm)
{
  vlib_simple_counter_main_t counter = {
    .name = "test-simple-counter-expand",
    .stat_segment_name = "/vlib/test-simple-counter-expand",
  };
  int i, index;
  uint64_t epoch, new_epoch;

  // Create one counter to allocate the vector.
  vlib_validate_simple_counter (&counter, 0);
  epoch = get_stats_epoch ();

  for (i = 0; i < EXPAND_TEST_ROUNDS; i++)
    {
      // Check how many elements fit into the counter vector without expanding
      // that. The next validate calls should not increase the stats segment
      // epoch.
      int mem_size = vec_max_len (counter.counters[0]);
      for (index = 1; index <= mem_size - 1; index++)
	{
	  vlib_validate_simple_counter (&counter, index);
	  new_epoch = get_stats_epoch ();
	  if (new_epoch != epoch)
	    return clib_error_return (
	      0, "Stats segment epoch should not increase");
	}

      // The next counter index does not fit and it will extend the vector.
      // The stats segment epoch should increase.
      vlib_validate_simple_counter (&counter, index + 1);
      new_epoch = get_stats_epoch ();
      if (new_epoch == epoch)
	return clib_error_return (0,
				  "Stats segment epoch should have increased");
      epoch = new_epoch;
    }

  vlib_free_simple_counter (&counter);
  vlib_validate_simple_counter (&counter, 0);

  return 0;
}

/*
 * Let a combined counter vector grow and verify that
 * the stats epoch is increased only when the vector
 * is expanded.
 */
static clib_error_t *
test_combined_counter_expand (vlib_main_t *vm)
{
  vlib_combined_counter_main_t counter = {
    .name = "test-combined-counter-expand",
    .stat_segment_name = "/vlib/test-combined-counter-expand",
  };
  int i, index;
  uint64_t epoch, new_epoch;

  // Create one counter to allocate the vector.
  vlib_validate_combined_counter (&counter, 0);
  epoch = get_stats_epoch ();

  for (i = 0; i < EXPAND_TEST_ROUNDS; i++)
    {
      // Check how many elements fit into the counter vector without expanding
      // that. The next validate calls should not increase the stats segment
      // epoch.
      int mem_size = vec_max_len (counter.counters[0]);
      for (index = 1; index <= mem_size - 1; index++)
	{
	  vlib_validate_combined_counter (&counter, index);
	  new_epoch = get_stats_epoch ();
	  if (new_epoch != epoch)
	    return clib_error_return (
	      0, "Stats segment epoch should not increase");
	}

      // The next counter index does not fit and it will extend the vector.
      // The stats segment epoch should increase.
      vlib_validate_combined_counter (&counter, index + 1);
      new_epoch = get_stats_epoch ();
      if (new_epoch == epoch)
	return clib_error_return (0,
				  "Stats segment epoch should have increased");
      epoch = new_epoch;
    }

  vlib_free_combined_counter (&counter);
  vlib_validate_combined_counter (&counter, 0);

  return 0;
}

static clib_error_t *
test_simple_counter (vlib_main_t *vm, int test_case)
{
  clib_error_t *error;

  switch (test_case)
    {
    case test_expand:
      error = test_simple_counter_expand (vm);
      break;

    default:
      return clib_error_return (0, "no such test");
    }

  return error;
}

static clib_error_t *
test_combined_counter (vlib_main_t *vm, int test_case)
{
  clib_error_t *error;

  switch (test_case)
    {
    case test_expand:
      error = test_combined_counter_expand (vm);
      break;

    default:
      return clib_error_return (0, "no such test");
    }

  return error;
}

static clib_error_t *
test_counter_command_fn (vlib_main_t *vm, unformat_input_t *input,
			 vlib_cli_command_t *cmd)
{
  clib_error_t *error;
  int counter_type = -1;
  int test_case = -1;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "simple"))
	counter_type = type_simple;
      else if (unformat (input, "combined"))
	counter_type = type_combined;
      else if (unformat (input, "expand"))
	test_case = test_expand;
      else
	return clib_error_return (0, "unknown input '%U'",
				  format_unformat_error, input);
    }

  if (test_case == -1)
    return clib_error_return (0, "no such test");

  switch (counter_type)
    {
    case type_simple:
      error = test_simple_counter (vm, test_case);
      break;

    case type_combined:
      error = test_combined_counter (vm, test_case);
      break;

    default:
      return clib_error_return (0, "no such test");
    }

  return error;
}

VLIB_CLI_COMMAND (test_counter_command, static) = {
  .path = "test counter",
  .short_help = "test counter [simple | combined] expand",
  .function = test_counter_command_fn,
};

static clib_error_t *
test_counter_init (vlib_main_t *vm)
{
  return (0);
}

VLIB_INIT_FUNCTION (test_counter_init);

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
