/*
 * Copyright (c) 2017-2019 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.
 */
#include <vnet/session/application.h>
#include <vnet/session/session.h>

u8 *
format_session_fifos (u8 * s, va_list * args)
{
  session_t *ss = va_arg (*args, session_t *);
  int verbose = va_arg (*args, int);
  session_event_t _e, *e = &_e;
  u8 found;

  if (!ss->rx_fifo || !ss->tx_fifo)
    return s;

  s = format (s, " Rx fifo: %U", format_svm_fifo, ss->rx_fifo, verbose);
  if (verbose > 2 && ss->rx_fifo->has_event)
    {
      found = session_node_lookup_fifo_event (ss->rx_fifo, e);
      s = format (s, " session node event: %s\n",
		  found ? "found" : "not found");
    }
  s = format (s, " Tx fifo: %U", format_svm_fifo, ss->tx_fifo, verbose);
  if (verbose > 2 && ss->tx_fifo->has_event)
    {
      found = session_node_lookup_fifo_event (ss->tx_fifo, e);
      s = format (s, " session node event: %s\n",
		  found ? "found" : "not found");
    }
  return s;
}

/**
 * Format stream session as per the following format
 *
 * verbose:
 *   "Connection", "Rx fifo", "Tx fifo", "Session Index"
 * non-verbose:
 *   "Connection"
 */
u8 *
format_session (u8 * s, va_list * args)
{
  session_t *ss = va_arg (*args, session_t *);
  int verbose = va_arg (*args, int);
  u32 tp = session_get_transport_proto (ss);
  u8 *str = 0;

  if (ss->session_state >= SESSION_STATE_TRANSPORT_DELETED)
    {
      s = format (s, "[%u:%u] CLOSED", ss->thread_index, ss->session_index);
      return s;
    }

  if (verbose == 1)
    {
      u8 post_accept = ss->session_state >= SESSION_STATE_ACCEPTING;
      u8 hasf = post_accept
	|| session_transport_service_type (ss) == TRANSPORT_SERVICE_CL;
      u32 rxf, txf;

      rxf = hasf ? svm_fifo_max_dequeue (ss->rx_fifo) : 0;
      txf = hasf ? svm_fifo_max_dequeue (ss->tx_fifo) : 0;
      str = format (0, "%-10u%-10u", rxf, txf);
    }

  if (ss->session_state >= SESSION_STATE_ACCEPTING
      || ss->session_state == SESSION_STATE_CREATED)
    {
      s = format (s, "%U", format_transport_connection, tp,
		  ss->connection_index, ss->thread_index, verbose);
      if (verbose == 1)
	s = format (s, "%v", str);
      if (verbose > 1)
	s = format (s, "%U", format_session_fifos, ss, verbose);
    }
  else if (ss->session_state == SESSION_STATE_LISTENING)
    {
      s = format (s, "%U%v", format_transport_listen_connection,
		  tp, ss->connection_index, ss->thread_index, verbose, str);
      if (verbose > 1)
	s = format (s, "\n%U", format_session_fifos, ss, verbose);
    }
  else if (ss->session_state == SESSION_STATE_CONNECTING)
    {
      s = format (s, "%-40U%v", format_transport_half_open_connection,
		  tp, ss->connection_index, ss->thread_index, str);
    }
  else
    {
      clib_warning ("Session in state: %d!", ss->session_state);
    }
  vec_free (str);

  return s;
}

uword
unformat_stream_session_id (unformat_input_t * input, va_list * args)
{
  u8 *proto = va_arg (*args, u8 *);
  u32 *fib_index = va_arg (*args, u32 *);
  ip46_address_t *lcl = va_arg (*args, ip46_address_t *);
  ip46_address_t *rmt = va_arg (*args, ip46_address_t *);
  u16 *lcl_port = va_arg (*args, u16 *);
  u16 *rmt_port = va_arg (*args, u16 *);
  u8 *is_ip4 = va_arg (*args, u8 *);
  u8 tuple_is_set = 0;
  u32 vrf = ~0;

  clib_memset (lcl, 0, sizeof (*lcl));
  clib_memset (rmt, 0, sizeof (*rmt));

  if (unformat (input, "tcp"))
    {
      *proto = TRANSPORT_PROTO_TCP;
    }
  else if (unformat (input, "udp"))
    {
      *proto = TRANSPORT_PROTO_UDP;
    }
  else
    return 0;

  if (unformat (input, "vrf %u", &vrf))
    ;

  if (unformat (input, "%U:%d->%U:%d", unformat_ip4_address, &lcl->ip4,
		lcl_port, unformat_ip4_address, &rmt->ip4, rmt_port))
    {
      *is_ip4 = 1;
      tuple_is_set = 1;
    }
  else if (unformat (input, "%U:%d->%U:%d", unformat_ip6_address, &lcl->ip6,
		     lcl_port, unformat_ip6_address, &rmt->ip6, rmt_port))
    {
      *is_ip4 = 0;
      tuple_is_set = 1;
    }

  if (vrf != ~0)
    {
      fib_protocol_t fib_proto;
      fib_proto = *is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
      *fib_index = fib_table_find (fib_proto, vrf);
    }

  return tuple_is_set;
}

uword
unformat_session_state (unformat_input_t * input, va_list * args)
{
  session_state_t *state = va_arg (*args, session_state_t *);
  u8 *state_vec = 0;
  int rv = 0;

#define _(sym, str)					\
  if (unformat (input, str))				\
    {							\
      *state = SESSION_STATE_ ## sym;			\
      rv = 1;						\
      goto done;					\
    }
  foreach_session_state
#undef _
done:
  vec_free (state_vec);
  return rv;
}

uword
unformat_session (unformat_input_t * input, va_list * args)
{
  session_t **result = va_arg (*args, session_t **);
  u32 lcl_port = 0, rmt_port = 0, fib_index = 0;
  ip46_address_t lcl, rmt;
  session_t *s;
  u8 proto = ~0;
  u8 is_ip4 = 0;

  if (!unformat (input, "%U", unformat_stream_session_id, &proto, &fib_index,
		 &lcl, &rmt, &lcl_port, &rmt_port, &is_ip4))
    return 0;

  if (is_ip4)
    s = session_lookup_safe4 (fib_index, &lcl.ip4, &rmt.ip4,
			      clib_host_to_net_u16 (lcl_port),
			      clib_host_to_net_u16 (rmt_port), proto);
  else
    s = session_lookup_safe6 (fib_index, &lcl.ip6, &rmt.ip6,
			      clib_host_to_net_u16 (lcl_port),
			      clib_host_to_net_u16 (rmt_port), proto);
  if (s)
    {
      *result = s;
      session_pool_remove_peeker (s->thread_index);
      return 1;
    }
  return 0;
}

uword
unformat_transport_connection (unformat_input_t * input, va_list * args)
{
  transport_connection_t **result = va_arg (*args, transport_connection_t **);
  u32 suggested_proto = va_arg (*args, u32);
  transport_connection_t *tc;
  u8 proto = ~0;
  ip46_address_t lcl, rmt;
  u32 lcl_port = 0, rmt_port = 0, fib_index = 0;
  u8 is_ip4 = 0;

  if (!unformat (input, "%U", unformat_stream_session_id, &fib_index, &proto,
		 &lcl, &rmt, &lcl_port, &rmt_port, &is_ip4))
    return 0;

  proto = (proto == (u8) ~ 0) ? suggested_proto : proto;
  if (proto == (u8) ~ 0)
    return 0;
  if (is_ip4)
    tc = session_lookup_connection4 (fib_index, &lcl.ip4, &rmt.ip4,
				     clib_host_to_net_u16 (lcl_port),
				     clib_host_to_net_u16 (rmt_port), proto);
  else
    tc = session_lookup_connection6 (fib_index, &lcl.ip6, &rmt.ip6,
				     clib_host_to_net_u16 (lcl_port),
				     clib_host_to_net_u16 (rmt_port), proto);

  if (tc)
    {
      *result = tc;
      return 1;
    }
  return 0;
}

static void
session_cli_show_all_sessions (vlib_main_t * vm, int verbose)
{
  session_main_t *smm = &session_main;
  u32 n_closed, thread_index;
  session_t *pool, *s;

  for (thread_index = 0; thread_index < vec_len (smm->wrk); thread_index++)
    {
      pool = smm->wrk[thread_index].sessions;

      if (!pool_elts (pool))
	{
	  vlib_cli_output (vm, "Thread %d: no sessions", thread_index);
	  continue;
	}

      if (!verbose)
	{
	  vlib_cli_output (vm, "Thread %d: %d sessions", thread_index,
			   pool_elts (pool));
	  continue;
	}

      if (pool_elts (pool) > 50)
	{
	  vlib_cli_output (vm, "Thread %u: %d sessions. Verbose output "
			   "suppressed. For more details use filters.",
			   thread_index, pool_elts (pool));
	  continue;
	}

      if (verbose == 1)
	vlib_cli_output (vm, "%s%-50s%-15s%-10s%-10s",
			 thread_index ? "\n" : "",
			 "Connection", "State", "Rx-f", "Tx-f");

      n_closed = 0;

      /* *INDENT-OFF* */
      pool_foreach(s, pool, ({
        if (s->session_state >= SESSION_STATE_TRANSPORT_DELETED)
          {
            n_closed += 1;
            continue;
          }
        vlib_cli_output (vm, "%U", format_session, s, verbose);
      }));
      /* *INDENT-ON* */

      if (!n_closed)
	vlib_cli_output (vm, "Thread %d: active sessions %u", thread_index,
			 pool_elts (pool) - n_closed);
      else
	vlib_cli_output (vm, "Thread %d: active sessions %u closed %u",
			 thread_index, pool_elts (pool) - n_closed, n_closed);
    }
}

static int
session_cli_filter_check (session_t * s, session_state_t * states,
			  transport_proto_t tp)
{
  if (states)
    {
      session_state_t *state;
      vec_foreach (state, states) if (s->session_state == *state)
	goto check_transport;
      return 0;
    }

check_transport:

  if (tp != TRANSPORT_N_PROTO && session_get_transport_proto (s) != tp)
    return 0;

  return 1;
}

static void
session_cli_show_session_filter (vlib_main_t * vm, u32 thread_index,
				 u32 start, u32 end, session_state_t * states,
				 transport_proto_t tp, int verbose)
{
  u8 output_suppressed = 0;
  session_worker_t *wrk;
  session_t *pool, *s;
  u32 count = 0, max_index;
  int i;

  wrk = session_main_get_worker_if_valid (thread_index);
  if (!wrk)
    {
      vlib_cli_output (vm, "invalid thread index %u", thread_index);
      return;
    }

  pool = wrk->sessions;

  if (tp == TRANSPORT_N_PROTO && states == 0 && !verbose
      && (start == 0 && end == ~0))
    {
      vlib_cli_output (vm, "Thread %d: %u sessions", thread_index,
		       pool_elts (pool));
      return;
    }

  max_index = pool_len (pool) ? pool_len (pool) - 1 : 0;
  for (i = start; i <= clib_min (end, max_index); i++)
    {
      if (pool_is_free_index (pool, i))
	continue;

      s = pool_elt_at_index (pool, i);

      if (session_cli_filter_check (s, states, tp))
	{
	  count += 1;
	  if (verbose)
	    {
	      if (count > 50 || (verbose > 1 && count > 10))
		{
		  output_suppressed = 1;
		  continue;
		}
	      if (s->session_state < SESSION_STATE_TRANSPORT_DELETED)
		vlib_cli_output (vm, "%U", format_session, s, verbose);
	    }
	}
    }

  if (!output_suppressed)
    vlib_cli_output (vm, "Thread %d: %u sessions matched filter",
		     thread_index, count);
  else
    vlib_cli_output (vm, "Thread %d: %u sessions matched filter. Not all"
		     " shown. Use finer grained filter.", thread_index,
		     count);
}

static void
session_cli_print_transport_protos (vlib_main_t * vm)
{
#define _(sym, str, sstr) vlib_cli_output (vm, str);
  foreach_transport_proto
#undef _
}

static void
session_cli_print_session_states (vlib_main_t * vm)
{
#define _(sym, str) vlib_cli_output (vm, str);
  foreach_session_state
#undef _
}

static clib_error_t *
show_session_command_fn (vlib_main_t * vm, unformat_input_t * input,
			 vlib_cli_command_t * cmd)
{
  u8 one_session = 0, do_listeners = 0, sst, do_elog = 0, do_filter = 0;
  u32 track_index, thread_index = 0, start = 0, end = ~0, session_index;
  unformat_input_t _line_input, *line_input = &_line_input;
  transport_proto_t transport_proto = TRANSPORT_N_PROTO;
  session_state_t state = SESSION_N_STATES, *states = 0;
  session_main_t *smm = &session_main;
  clib_error_t *error = 0;
  app_worker_t *app_wrk;
  u32 transport_index;
  const u8 *app_name;
  int verbose = 0;
  session_t *s;

  session_cli_return_if_not_enabled ();

  if (!unformat_user (input, unformat_line_input, line_input))
    {
      session_cli_show_all_sessions (vm, 0);
      return 0;
    }

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "verbose %d", &verbose))
	;
      else if (unformat (line_input, "verbose"))
	verbose = 1;
      else if (unformat (line_input, "listeners %U", unformat_transport_proto,
			 &transport_proto))
	do_listeners = 1;
      else if (unformat (line_input, "%U", unformat_session, &s))
	{
	  one_session = 1;
	}
      else if (unformat (line_input, "thread %u index %u", &thread_index,
			 &session_index))
	{
	  s = session_get_if_valid (session_index, thread_index);
	  if (!s)
	    {
	      vlib_cli_output (vm, "session is not allocated");
	      goto done;
	    }
	  one_session = 1;
	}
      else if (unformat (line_input, "thread %u", &thread_index))
	{
	  do_filter = 1;
	}
      else
	if (unformat (line_input, "state %U", unformat_session_state, &state))
	{
	  vec_add1 (states, state);
	  do_filter = 1;
	}
      else if (unformat (line_input, "proto %U index %u",
			 unformat_transport_proto, &transport_proto,
			 &transport_index))
	{
	  transport_connection_t *tc;
	  tc = transport_get_connection (transport_proto, transport_index,
					 thread_index);
	  if (!tc)
	    {
	      vlib_cli_output (vm, "transport connection %u thread %u is not"
			       " allocated", transport_index, thread_index);
	      goto done;
	    }
	  s = session_get_if_valid (tc->s_index, thread_index);
	  if (!s)
	    {
	      vlib_cli_output (vm, "session for transport connection %u "
			       "thread %u does not exist", transport_index,
			       thread_index);
	      goto done;
	    }
	  one_session = 1;
	}
      else if (unformat (line_input, "proto %U", unformat_transport_proto,
			 &transport_proto))
	do_filter = 1;
      else if (unformat (line_input, "range %u %u", &start, &end))
	do_filter = 1;
      else if (unformat (line_input, "range %u", &start))
	{
	  end = start + 50;
	  do_filter = 1;
	}
      else if (unformat (line_input, "elog"))
	do_elog = 1;
      else if (unformat (line_input, "protos"))
	{
	  session_cli_print_transport_protos (vm);
	  goto done;
	}
      else if (unformat (line_input, "states"))
	{
	  session_cli_print_session_states (vm);
	  goto done;
	}
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  if (one_session)
    {
      u8 *str = format (0, "%U", format_session, s, 3);
      if (do_elog && s->session_state != SESSION_STATE_LISTENING)
	{
	  elog_main_t *em = &vm->elog_main;
	  transport_connection_t *tc;
	  f64 dt;

	  tc = session_get_transport (s);
	  track_index = transport_elog_track_index (tc);
	  dt = (em->init_time.cpu - vm->clib_time.init_cpu_time)
	    * vm->clib_time.seconds_per_clock;
	  if (track_index != ~0)
	    str = format (str, " session elog:\n%U", format_elog_track, em,
			  dt, track_index);
	}
      vlib_cli_output (vm, "%v", str);
      vec_free (str);
      goto done;
    }

  if (do_listeners)
    {
      sst = session_type_from_proto_and_ip (transport_proto, 1);
      vlib_cli_output (vm, "%-50s%-24s", "Listener", "App");
      /* *INDENT-OFF* */
      pool_foreach (s, smm->wrk[0].sessions, ({
	if (s->session_state != SESSION_STATE_LISTENING
	    || s->session_type != sst)
	  continue;
	app_wrk = app_worker_get (s->app_wrk_index);
	app_name = application_name_from_index (app_wrk->app_index);
	vlib_cli_output (vm, "%U%-25v%", format_session, s, 0,
			 app_name);
      }));
      /* *INDENT-ON* */
      goto done;
    }

  if (do_filter)
    {
      if (end < start)
	{
	  error = clib_error_return (0, "invalid range start: %u end: %u",
				     start, end);
	  goto done;
	}
      session_cli_show_session_filter (vm, thread_index, start, end, states,
				       transport_proto, verbose);
      goto done;
    }

  session_cli_show_all_sessions (vm, verbose);

done:
  unformat_free (line_input);
  vec_free (states);
  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (vlib_cli_show_session_command) =
{
  .path = "show session",
  .short_help = "show session [verbose [n]] [listeners <proto>] "
		"[<session-id> [elog]] [thread <n> [index <n>] "
		"[proto <proto>] [state <state>] [range <min> [<max>]] "
		"[protos] [states] ",
  .function = show_session_command_fn,
};
/* *INDENT-ON* */

static int
clear_session (session_t * s)
{
  app_worker_t *server_wrk = app_worker_get (s->app_wrk_index);
  app_worker_close_notify (server_wrk, s);
  return 0;
}

static clib_error_t *
clear_session_command_fn (vlib_main_t * vm, unformat_input_t * input,
			  vlib_cli_command_t * cmd)
{
  session_main_t *smm = &session_main;
  u32 thread_index = 0, clear_all = 0;
  session_worker_t *wrk;
  u32 session_index = ~0;
  session_t *session;

  if (!smm->is_enabled)
    {
      return clib_error_return (0, "session layer is not enabled");
    }

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "thread %d", &thread_index))
	;
      else if (unformat (input, "session %d", &session_index))
	;
      else if (unformat (input, "all"))
	clear_all = 1;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if (!clear_all && session_index == ~0)
    return clib_error_return (0, "session <nn> required, but not set.");

  if (session_index != ~0)
    {
      session = session_get_if_valid (session_index, thread_index);
      if (!session)
	return clib_error_return (0, "no session %d on thread %d",
				  session_index, thread_index);
      clear_session (session);
    }

  if (clear_all)
    {
      /* *INDENT-OFF* */
      vec_foreach (wrk, smm->wrk)
	{
	  pool_foreach(session, wrk->sessions, ({
	    clear_session (session);
	  }));
	};
      /* *INDENT-ON* */
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (clear_session_command, static) =
{
  .path = "clear session",
  .short_help = "clear session thread <thread> session <index>",
  .function = clear_session_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
show_session_fifo_trace_command_fn (vlib_main_t * vm,
				    unformat_input_t * input,
				    vlib_cli_command_t * cmd)
{
  session_t *s = 0;
  u8 is_rx = 0, *str = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%U", unformat_session, &s))
	;
      else if (unformat (input, "rx"))
	is_rx = 1;
      else if (unformat (input, "tx"))
	is_rx = 0;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if (!SVM_FIFO_TRACE)
    {
      vlib_cli_output (vm, "fifo tracing not enabled");
      return 0;
    }

  if (!s)
    {
      vlib_cli_output (vm, "could not find session");
      return 0;
    }

  str = is_rx ?
    svm_fifo_dump_trace (str, s->rx_fifo) :
    svm_fifo_dump_trace (str, s->tx_fifo);

  vlib_cli_output (vm, "%v", str);
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_session_fifo_trace_command, static) =
{
  .path = "show session fifo trace",
  .short_help = "show session fifo trace <session>",
  .function = show_session_fifo_trace_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
session_replay_fifo_command_fn (vlib_main_t * vm, unformat_input_t * input,
				vlib_cli_command_t * cmd)
{
  session_t *s = 0;
  u8 is_rx = 0, *str = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%U", unformat_session, &s))
	;
      else if (unformat (input, "rx"))
	is_rx = 1;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if (!SVM_FIFO_TRACE)
    {
      vlib_cli_output (vm, "fifo tracing not enabled");
      return 0;
    }

  if (!s)
    {
      vlib_cli_output (vm, "could not find session");
      return 0;
    }

  str = is_rx ?
    svm_fifo_replay (str, s->rx_fifo, 0, 1) :
    svm_fifo_replay (str, s->tx_fifo, 0, 1);

  vlib_cli_output (vm, "%v", str);
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (session_replay_fifo_trace_command, static) =
{
  .path = "session replay fifo",
  .short_help = "session replay fifo <session>",
  .function = session_replay_fifo_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
session_enable_disable_fn (vlib_main_t * vm, unformat_input_t * input,
			   vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u8 is_en = 1;
  clib_error_t *error;

  if (!unformat_user (input, unformat_line_input, line_input))
    return clib_error_return (0, "expected enable | disable");

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "enable"))
	is_en = 1;
      else if (unformat (line_input, "disable"))
	is_en = 0;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  unformat_free (line_input);
	  return error;
	}
    }

  unformat_free (line_input);
  return vnet_session_enable_disable (vm, is_en);
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (session_enable_disable_command, static) =
{
  .path = "session",
  .short_help = "session [enable|disable]",
  .function = session_enable_disable_fn,
};
/* *INDENT-ON* */

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