/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * 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.
 */
/*
 * error.c: VLIB error handler
 *
 * Copyright (c) 2008 Eliot Dresselhaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <vlib/vlib.h>
#include <vppinfra/heap.h>
#include <vlib/stats/stats.h>

uword
vlib_error_drop_buffers (vlib_main_t * vm,
			 vlib_node_runtime_t * node,
			 u32 * buffers,
			 u32 next_buffer_stride,
			 u32 n_buffers,
			 u32 next_index,
			 u32 drop_error_node, u32 drop_error_code)
{
  u32 n_left_this_frame, n_buffers_left, *args, n_args_left;
  vlib_error_t drop_error;
  vlib_node_t *n;

  n = vlib_get_node (vm, drop_error_node);
  drop_error = n->error_heap_index + drop_error_code;

  n_buffers_left = n_buffers;
  while (n_buffers_left > 0)
    {
      vlib_get_next_frame (vm, node, next_index, args, n_args_left);

      n_left_this_frame = clib_min (n_buffers_left, n_args_left);
      n_buffers_left -= n_left_this_frame;
      n_args_left -= n_left_this_frame;

      while (n_left_this_frame >= 4)
	{
	  u32 bi0, bi1, bi2, bi3;
	  vlib_buffer_t *b0, *b1, *b2, *b3;

	  args[0] = bi0 = buffers[0];
	  args[1] = bi1 = buffers[1];
	  args[2] = bi2 = buffers[2];
	  args[3] = bi3 = buffers[3];

	  b0 = vlib_get_buffer (vm, bi0);
	  b1 = vlib_get_buffer (vm, bi1);
	  b2 = vlib_get_buffer (vm, bi2);
	  b3 = vlib_get_buffer (vm, bi3);

	  b0->error = drop_error;
	  b1->error = drop_error;
	  b2->error = drop_error;
	  b3->error = drop_error;

	  buffers += 4;
	  args += 4;
	  n_left_this_frame -= 4;
	}

      while (n_left_this_frame >= 1)
	{
	  u32 bi0;
	  vlib_buffer_t *b0;

	  args[0] = bi0 = buffers[0];

	  b0 = vlib_get_buffer (vm, bi0);
	  b0->error = drop_error;

	  buffers += 1;
	  args += 1;
	  n_left_this_frame -= 1;
	}

      vlib_put_next_frame (vm, node, next_index, n_args_left);
    }

  return n_buffers;
}

/* Reserves given number of error codes for given node. */
void
vlib_register_errors (vlib_main_t *vm, u32 node_index, u32 n_errors,
		      char *error_strings[], vlib_error_desc_t counters[])
{
  vlib_error_main_t *em = &vm->error_main;
  vlib_node_main_t *nm = &vm->node_main;

  vlib_node_t *n = vlib_get_node (vm, node_index);
  uword l;
  void *oldheap;

  ASSERT (vlib_get_thread_index () == 0);

  /* Free up any previous error strings. */
  if (n->n_errors > 0)
    heap_dealloc (em->counters_heap, n->error_heap_handle);

  n->n_errors = n_errors;
  n->error_counters = counters;

  if (n_errors == 0)
    return;

  /*  Legacy node */
  if (!counters)
    {
      counters = clib_mem_alloc (sizeof (counters[0]) * n_errors);
      int i;
      for (i = 0; i < n_errors; i++)
	{
	  counters[i].name = error_strings[i];
	  counters[i].desc = error_strings[i];
	  counters[i].severity = VL_COUNTER_SEVERITY_ERROR;
	}
    }

  n->error_heap_index =
    heap_alloc (em->counters_heap, n_errors, n->error_heap_handle);
  l = vec_len (em->counters_heap);
  clib_memcpy (vec_elt_at_index (em->counters_heap, n->error_heap_index),
	       counters, n_errors * sizeof (counters[0]));

  vec_validate (vm->error_elog_event_types, l - 1);

  /* Switch to the stats segment ... */
  oldheap = vlib_stats_set_heap ();

  /* Allocate a counter/elog type for each error. */
  vec_validate (em->counters, l - 1);

  /* Zero counters for re-registrations of errors. */
  if (n->error_heap_index + n_errors <= vec_len (em->counters_last_clear))
    clib_memcpy (em->counters + n->error_heap_index,
		 em->counters_last_clear + n->error_heap_index,
		 n_errors * sizeof (em->counters[0]));
  else
    clib_memset (em->counters + n->error_heap_index,
		 0, n_errors * sizeof (em->counters[0]));

  oldheap = clib_mem_set_heap (oldheap);

  /* Register counter indices in the stat segment directory */
  {
    int i;

    for (i = 0; i < n_errors; i++)
      {
	vlib_stats_register_error_index (em->counters, n->error_heap_index + i,
					 "/err/%v/%s", n->name,
					 counters[i].name);
      }

  }

  /* (re)register the em->counters base address, switch back to main heap */
  vlib_stats_update_error_vector (em->counters, vm->thread_index, 1);

  {
    elog_event_type_t t;
    uword i;

    clib_memset (&t, 0, sizeof (t));
    if (n_errors > 0)
      vec_validate (nm->node_by_error, n->error_heap_index + n_errors - 1);
    for (i = 0; i < n_errors; i++)
      {
	t.format = (char *) format (0, "%v %s: %%d",
				    n->name, counters[i].name);
	vm->error_elog_event_types[n->error_heap_index + i] = t;
	nm->node_by_error[n->error_heap_index + i] = n->index;
      }
  }
}

uword
unformat_vlib_error (unformat_input_t *input, va_list *args)
{
  vlib_main_t *vm = va_arg (*args, vlib_main_t *);
  const vlib_error_main_t *em = &vm->error_main;
  vlib_error_t *error_index = va_arg (*args, vlib_error_t *);
  const vlib_node_t *node;
  char *error_name;
  u32 node_index;
  vlib_error_t i;

  if (!unformat (input, "%U.%s", unformat_vlib_node, vm, &node_index,
		 &error_name))
    return 0;

  node = vlib_get_node (vm, node_index);
  for (i = 0; i < node->n_errors; i++)
    {
      vlib_error_t ei = node->error_heap_index + i;
      if (strcmp (em->counters_heap[ei].name, error_name) == 0)
	{
	  *error_index = ei;
	  vec_free (error_name);
	  return 1;
	}
    }

  vec_free (error_name);
  return 0;
}

static char *
sev2str (enum vl_counter_severity_e s)
{
  switch (s)
    {
    case VL_COUNTER_SEVERITY_ERROR:
      return "error";
    case VL_COUNTER_SEVERITY_WARN:
      return "warn";
    case VL_COUNTER_SEVERITY_INFO:
      return "info";
    default:
      return "unknown";
    }
}

static clib_error_t *
show_errors (vlib_main_t * vm,
	     unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vlib_error_main_t *em = &vm->error_main;
  vlib_node_t *n;
  u32 code, i, ni;
  u64 c;
  int index = 0;
  int verbose = 0;
  u64 *sums = 0;

  if (unformat (input, "verbose %d", &verbose))
    ;
  else if (unformat (input, "verbose"))
    verbose = 1;

  vec_validate (sums, vec_len (em->counters));

  if (verbose)
    vlib_cli_output (vm, "%=10s%=35s%=35s%=10s%=6s", "Count", "Node",
		     "Reason", "Severity", "Index");
  else
    vlib_cli_output (vm, "%=10s%=35s%=35s%=10s", "Count", "Node", "Reason",
		     "Severity");

  foreach_vlib_main ()
    {
      em = &this_vlib_main->error_main;

      if (verbose)
	vlib_cli_output (vm, "Thread %u (%v):", index,
			 vlib_worker_threads[index].name);

      for (ni = 0; ni < vec_len (this_vlib_main->node_main.nodes); ni++)
	{
	  n = vlib_get_node (this_vlib_main, ni);
	  for (code = 0; code < n->n_errors; code++)
	    {
	      i = n->error_heap_index + code;
	      c = em->counters[i];
	      if (i < vec_len (em->counters_last_clear))
		c -= em->counters_last_clear[i];
	      sums[i] += c;

	      if (c == 0 && verbose < 2)
		continue;

	      if (verbose)
		vlib_cli_output (vm, "%10lu%=35v%=35s%=10s%=6d", c, n->name,
				 em->counters_heap[i].desc,
				 sev2str (em->counters_heap[i].severity), i);
	      else
		vlib_cli_output (vm, "%10lu%=35v%=35s%=10s", c, n->name,
				 em->counters_heap[i].desc,
				 sev2str (em->counters_heap[i].severity));
	    }
	}
      index++;
    }

  if (verbose)
    vlib_cli_output (vm, "Total:");

  for (ni = 0; ni < vec_len (vm->node_main.nodes); ni++)
    {
      n = vlib_get_node (vm, ni);
      for (code = 0; code < n->n_errors; code++)
	{
	  i = n->error_heap_index + code;
	  if (sums[i])
	    {
	      if (verbose)
		vlib_cli_output (vm, "%10lu%=40v%=20s%=10d", sums[i], n->name,
				 em->counters_heap[i].desc, i);
	    }
	}
    }

  vec_free (sums);

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (vlib_cli_show_errors) = {
  .path = "show errors",
  .short_help = "Show error counts",
  .function = show_errors,
};
/* *INDENT-ON* */

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (cli_show_node_counters, static) = {
  .path = "show node counters",
  .short_help = "Show node counters",
  .function = show_errors,
};
/* *INDENT-ON* */

static clib_error_t *
clear_error_counters (vlib_main_t * vm,
		      unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vlib_error_main_t *em;
  u32 i;

  foreach_vlib_main ()
    {
      em = &this_vlib_main->error_main;
      vec_validate (em->counters_last_clear, vec_len (em->counters) - 1);
      for (i = 0; i < vec_len (em->counters); i++)
	em->counters_last_clear[i] = em->counters[i];
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (cli_clear_error_counters, static) = {
  .path = "clear errors",
  .short_help = "Clear error counters",
  .function = clear_error_counters,
};
/* *INDENT-ON* */

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (cli_clear_node_counters, static) = {
  .path = "clear node counters",
  .short_help = "Clear node counters",
  .function = clear_error_counters,
};
/* *INDENT-ON* */

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