/*
 * 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.
 */
/**
 * @file
 * @brief Host utility functions
 */
#include <vppinfra/format.h>
#include <vlib/vlib.h>

#include <vlib/threads.h>
#include <vnet/vnet.h>
#include <vppinfra/format.h>

/**
 * @brief GDB callable function: vl - Return vector length of vector
 *
 * @param *p - void - address of vector
 *
 * @return length - u32
 *
 */
u32
vl (void *p)
{
  return vec_len (p);
}

/**
 * @brief GDB callable function: pvh - Return vector header of vector
 *
 * @param *p - void - address of vector
 *
 * @return vh - vec_header_t, the vector header
 *
 */
vec_header_t *
pvh (void *p)
{
  return _vec_find (p);
}


/**
 * @brief GDB callable function: pe - call pool_elts - number of elements in a pool
 *
 * @param *v - void - address of pool
 *
 * @return number - uword
 *
 */
uword
pe (void *v)
{
  return (pool_elts (v));
}

/**
 * @brief GDB callable function: ph - call pool_header - get pool header.
 *
 * @param *p - void - address of pool
 *
 * @return pool_header_t
 *
 */
pool_header_t *
ph (void *p)
{
  return pool_header (p);
}

/**
 * @brief GDB callable function: pifi - call pool_is_free_index - is passed index free?
 *
 * @param *p - void - address of pool
 * @param *index - u32
 *
 * @return 0|1 - int
 *
 */
int
pifi (void *p, u32 index)
{
  return pool_is_free_index (p, index);
}

/**
 * @brief GDB callable function: debug_hex_bytes - return formatted hex string
 *
 * @param *s - u8
 * @param n - u32 - number of bytes to format
 *
 */
void
debug_hex_bytes (u8 * s, u32 n)
{
  fformat (stderr, "%U\n", format_hex_bytes, s, n);
}

/**
 * @brief GDB callable function: vlib_dump_frame_ownership
 *
 */
void
vlib_dump_frame_ownership (void)
{
  vlib_main_t *vm = vlib_get_main ();
  vlib_node_main_t *nm = &vm->node_main;
  vlib_node_runtime_t *this_node_runtime;
  vlib_next_frame_t *nf;
  u32 first_nf_index;
  u32 index;

  vec_foreach (this_node_runtime, nm->nodes_by_type[VLIB_NODE_TYPE_INTERNAL])
  {
    first_nf_index = this_node_runtime->next_frame_index;

    for (index = first_nf_index; index < first_nf_index +
	 this_node_runtime->n_next_nodes; index++)
      {
	vlib_node_runtime_t *owned_runtime;
	nf = vec_elt_at_index (vm->node_main.next_frames, index);
	if (nf->flags & VLIB_FRAME_OWNER)
	  {
	    owned_runtime = vec_elt_at_index (nm->nodes_by_type[0],
					      nf->node_runtime_index);
	    fformat (stderr,
		     "%s next index %d owns enqueue rights to %s\n",
		     nm->nodes[this_node_runtime->node_index]->name,
		     index - first_nf_index,
		     nm->nodes[owned_runtime->node_index]->name);
	    fformat (stderr, "  nf index %d nf->frame %p\n",
		     nf - vm->node_main.next_frames, nf->frame);
	  }
      }
  }
}

/**
 * @brief GDB callable function: vlib_runtime_index_to_node_name
 *
 * Takes node index and will return the node name.
 *
 * @param index - u32
 */
void
vlib_runtime_index_to_node_name (u32 index)
{
  vlib_main_t *vm = vlib_get_main ();
  vlib_node_main_t *nm = &vm->node_main;

  if (index >= vec_len (nm->nodes))
    {
      fformat (stderr, "%d out of range, max %d\n", vec_len (nm->nodes));
      return;
    }

  fformat (stderr, "node runtime index %d name %s\n", index,
	   nm->nodes[index]->name);
}

void
gdb_show_errors (int verbose)
{
  extern vlib_cli_command_t vlib_cli_show_errors;
  unformat_input_t input;
  vlib_main_t *vm = vlib_get_main ();

  if (verbose == 0)
    unformat_init_string (&input, "verbose 0", 9);
  else if (verbose == 1)
    unformat_init_string (&input, "verbose 1", 9);
  else
    {
      fformat (stderr, "verbose not 0 or 1\n");
      return;
    }

  vlib_cli_show_errors.function (vm, &input, 0 /* cmd */ );
  unformat_free (&input);
}

void
gdb_show_session (int verbose)
{
  extern vlib_cli_command_t vlib_cli_show_session_command;
  unformat_input_t input;
  vlib_main_t *vm = vlib_get_main ();

  if (verbose == 0)
    unformat_init_string (&input, "verbose 0", 9);
  else if (verbose == 1)
    unformat_init_string (&input, "verbose 1", 9);
  else if (verbose == 2)
    unformat_init_string (&input, "verbose 2", 9);
  else
    {
      fformat (stderr, "verbose not 0 - 2\n");
      return;
    }

  vlib_cli_show_session_command.function (vm, &input, 0 /* cmd */ );
  unformat_free (&input);
}

static int
trace_cmp (void *a1, void *a2)
{
  vlib_trace_header_t **t1 = a1;
  vlib_trace_header_t **t2 = a2;
  i64 dt = t1[0]->time - t2[0]->time;
  return dt < 0 ? -1 : (dt > 0 ? +1 : 0);
}

void
gdb_show_traces ()
{
  vlib_trace_main_t *tm;
  vlib_trace_header_t **h, **traces;
  u32 i, index = 0;
  char *fmt;
  u8 *s = 0;
  u32 max;

  /* By default display only this many traces. */
  max = 50;

  /* Get active traces from pool. */

  foreach_vlib_main__ (0 /* no checks */)
  {
    fmt = "------------------- Start of thread %d %s -------------------\n";
    s = format (s, fmt, index, vlib_worker_threads[index].name);

    tm = &this_vlib_main->trace_main;

    trace_apply_filter (this_vlib_main);

    traces = 0;
    pool_foreach (h, tm->trace_buffer_pool)
      {
	vec_add1 (traces, h[0]);
      }

    if (vec_len (traces) == 0)
      {
	s = format (s, "No packets in trace buffer\n");
	goto done;
      }

    /* Sort them by increasing time. */
    vec_sort_with_function (traces, trace_cmp);

    for (i = 0; i < vec_len (traces); i++)
      {
	if (i == max)
	  {
	    fformat (stderr,
		     "Limiting display to %d packets."
		     " To display more specify max.",
		     max);
	    goto done;
	  }

	s = format (s, "Packet %d\n%U\n\n", i + 1, format_vlib_trace,
		    vlib_get_first_main (), traces[i]);
      }

    done:
      vec_free (traces);

      index++;
    }

  fformat (stderr, "%v", s);
  vec_free (s);
}

/**
 * @brief GDB callable function: show_gdb_command_fn - show gdb
 *
 * Shows list of functions for VPP available in GDB
 *
 * @return error - clib_error_t
 */
static clib_error_t *
show_gdb_command_fn (vlib_main_t * vm,
		     unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vlib_cli_output (vm, "vl(p) returns vec_len(p)");
  vlib_cli_output (vm, "vb(b) returns vnet_buffer(b) [opaque]");
  vlib_cli_output (vm, "vb2(b) returns vnet_buffer2(b) [opaque2]");
  vlib_cli_output (vm, "vbi(b) returns b index");
  vlib_cli_output (vm,
		   "vgb(bi) returns vlib_get_buffer(vlib_get_main(), bi)");
  vlib_cli_output (vm, "pe(p) returns pool_elts(p)");
  vlib_cli_output (vm, "ph(p) returns pool_header(p)");
  vlib_cli_output (vm, "pifi(p, i) returns pool_is_free_index(p, i)");
  vlib_cli_output (vm, "gdb_show_errors(0|1) dumps error counters");
  vlib_cli_output (vm, "gdb_show_session dumps session counters");
  vlib_cli_output (vm, "gdb_show_traces() dumps buffer traces");
  vlib_cli_output (vm, "gdb_validate_buffer(b) check vlib_buffer b sanity");
  vlib_cli_output (vm, "debug_hex_bytes (ptr, n_bytes) dumps n_bytes in hex");
  vlib_cli_output (vm, "vlib_dump_frame_ownership() does what it says");
  vlib_cli_output (vm, "vlib_runtime_index_to_node_name (index) prints NN");

  return 0;
}

VLIB_CLI_COMMAND (show_gdb_funcs_command, static) = {
  .path = "show gdb",
  .short_help = "Describe functions which can be called from gdb",
  .function = show_gdb_command_fn,
};

vlib_buffer_t *
vgb (u32 bi)
{
  return vlib_get_buffer (vlib_get_main (), bi);
}

vnet_buffer_opaque_t *
vb (void *vb_arg)
{
  vlib_buffer_t *b = (vlib_buffer_t *) vb_arg;
  vnet_buffer_opaque_t *rv;

  rv = vnet_buffer (b);

  return rv;
}

vnet_buffer_opaque2_t *
vb2 (void *vb_arg)
{
  vlib_buffer_t *b = (vlib_buffer_t *) vb_arg;
  vnet_buffer_opaque2_t *rv;

  rv = vnet_buffer2 (b);

  return rv;
}

u32
vbi (vlib_buffer_t * b)
{
  vlib_main_t *vm = vlib_get_main ();
  vlib_buffer_main_t *bm = vm->buffer_main;
  u32 bi = pointer_to_uword (b) - bm->buffer_mem_start;
  bi >>= CLIB_LOG2_CACHE_LINE_BYTES;
  return bi;
}

int
gdb_validate_buffer (vlib_buffer_t * b)
{
  vlib_main_t *vm = vlib_get_main ();
  u32 bi = vbi (b);
  u8 *s =
    vlib_validate_buffers (vm, &bi, 0, 1, VLIB_BUFFER_KNOWN_ALLOCATED, 1);
  if (s)
    {
      fformat (stderr, "gdb_validate_buffer(): %v", s);
      return -1;
    }
  fformat (stderr, "gdb_validate_buffer(): no error found\n");
  return 0;
}

/**
 * Dump a trajectory trace, reasonably easy to call from gdb
 */
void
gdb_dump_trajectory_trace (u32 bi)
{
#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
  vlib_main_t *vm = vlib_get_main ();
  vlib_node_main_t *vnm = &vm->node_main;
  vlib_buffer_t *b;
  u16 *trace;
  u8 i;

  b = vlib_get_buffer (vm, bi);

  trace = b->trajectory_trace;

  fformat (stderr, "Context trace for bi %d b 0x%llx, visited %d\n", bi, b,
	   b->trajectory_nb);

  for (i = 0; i < b->trajectory_nb; i++)
    {
      u32 node_index;

      node_index = trace[i];

      if (node_index >= vec_len (vnm->nodes))
	{
	  fformat (stderr, "Skip bogus node index %d\n", node_index);
	  continue;
	}

      fformat (stderr, "%v (%d)\n", vnm->nodes[node_index]->name, node_index);
    }
#else
  fformat (stderr, "in vlib/buffers.h, "
		   "#define VLIB_BUFFER_TRACE_TRAJECTORY 1\n");

#endif
}

void
gdb_dump_buffer (vlib_buffer_t *b)
{
  fformat (stderr, "%U\n", format_vnet_buffer, b);
}

/* Cafeteria plan, maybe you don't want these functions */
clib_error_t *
gdb_func_init (vlib_main_t * vm)
{
  return 0;
}

VLIB_INIT_FUNCTION (gdb_func_init);

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