/*
 * Copyright (c) 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 <stdbool.h>
#include <vlib/vlib.h>
#include <vnet/crypto/crypto.h>

static clib_error_t *
show_crypto_engines_command_fn (vlib_main_t * vm,
				unformat_input_t * input,
				vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  vnet_crypto_main_t *cm = &crypto_main;
  vnet_crypto_engine_t *p;

  if (unformat_user (input, unformat_line_input, line_input))
    unformat_free (line_input);

  if (vec_len (cm->engines) == 0)
    {
      vlib_cli_output (vm, "No crypto engines registered");
      return 0;
    }

  vlib_cli_output (vm, "%-20s%-8s%s", "Name", "Prio", "Description");
  /* *INDENT-OFF* */
  vec_foreach (p, cm->engines)
    {
      vlib_cli_output (vm, "%-20s%-8u%s", p->name, p->priority, p->desc);
    }
  /* *INDENT-ON* */
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_crypto_engines_command, static) =
{
  .path = "show crypto engines",
  .short_help = "show crypto engines",
  .function = show_crypto_engines_command_fn,
};

static u8 *
format_vnet_crypto_engine_candidates (u8 * s, va_list * args)
{
  vnet_crypto_engine_t *e;
  vnet_crypto_main_t *cm = &crypto_main;
  u32 id = va_arg (*args, u32);
  u32 ei = va_arg (*args, u32);
  int is_chained = va_arg (*args, int);
  int is_async = va_arg (*args, int);

  if (is_async)
    {
      vec_foreach (e, cm->engines)
	{
	  if (e->enqueue_handlers[id] && e->dequeue_handler)
	    {
	      s = format (s, "%U", format_vnet_crypto_engine, e - cm->engines);
	      if (ei == e - cm->engines)
		s = format (s, "%c ", '*');
	      else
		s = format (s, " ");
	    }
	}

      return s;
    }
  else
    {
      vec_foreach (e, cm->engines)
	{
	  void * h = is_chained ? (void *) e->chained_ops_handlers[id]
	    : (void *) e->ops_handlers[id];

	  if (h)
	    {
	      s = format (s, "%U", format_vnet_crypto_engine, e - cm->engines);
	      if (ei == e - cm->engines)
		s = format (s, "%c ", '*');
	      else
		s = format (s, " ");
	    }
	}
      return s;
    }
}

static u8 *
format_vnet_crypto_handlers (u8 * s, va_list * args)
{
  vnet_crypto_alg_t alg = va_arg (*args, vnet_crypto_alg_t);
  vnet_crypto_main_t *cm = &crypto_main;
  vnet_crypto_alg_data_t *d = vec_elt_at_index (cm->algs, alg);
  u32 indent = format_get_indent (s);
  int i, first = 1;

  for (i = 0; i < VNET_CRYPTO_OP_N_TYPES; i++)
    {
      vnet_crypto_op_data_t *od;
      vnet_crypto_op_id_t id = d->op_by_type[i];

      if (id == 0)
	continue;

      od = cm->opt_data + id;
      if (first == 0)
        s = format (s, "\n%U", format_white_space, indent);
      s = format (s, "%-16U", format_vnet_crypto_op_type, od->type);

      s = format (s, "%-28U", format_vnet_crypto_engine_candidates, id,
          od->active_engine_index_simple, 0, 0);
      s = format (s, "%U", format_vnet_crypto_engine_candidates, id,
          od->active_engine_index_chained, 1, 0);
      first = 0;
    }
  return s;
}


static clib_error_t *
show_crypto_handlers_command_fn (vlib_main_t * vm,
			unformat_input_t * input, vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  int i;

  if (unformat_user (input, unformat_line_input, line_input))
    unformat_free (line_input);

  vlib_cli_output (vm, "%-16s%-16s%-28s%s", "Algo", "Type", "Simple",
      "Chained");

  for (i = 0; i < VNET_CRYPTO_N_ALGS; i++)
    vlib_cli_output (vm, "%-16U%U", format_vnet_crypto_alg, i,
		     format_vnet_crypto_handlers, i);

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_crypto_handlers_command, static) =
{
  .path = "show crypto handlers",
  .short_help = "show crypto handlers",
  .function = show_crypto_handlers_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
set_crypto_handler_command_fn (vlib_main_t * vm,
			       unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  vnet_crypto_main_t *cm = &crypto_main;
  int rc = 0;
  char **args = 0, *s, **arg, *engine = 0;
  int all = 0;
  clib_error_t *error = 0;
  crypto_op_class_type_t oct = CRYPTO_OP_BOTH;

  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "all"))
	all = 1;
      else if (unformat (line_input, "simple"))
	oct = CRYPTO_OP_SIMPLE;
      else if (unformat (line_input, "chained"))
	oct = CRYPTO_OP_CHAINED;
      else if (unformat (line_input, "both"))
	oct = CRYPTO_OP_BOTH;
      else if (unformat (line_input, "%s", &s))
	vec_add1 (args, s);
      else
	{
	  error = clib_error_return (0, "invalid params");
	  goto done;
	}
    }

  if ((vec_len (args) < 2 && !all) || (vec_len (args) == 0 && all))
    {
      error = clib_error_return (0, "missing cipher or engine!");
      goto done;
    }

  engine = vec_elt_at_index (args, vec_len (args) - 1)[0];
  vec_del1 (args, vec_len (args) - 1);

  if (all)
    {
      char *key;
      u8 *value;

      /* *INDENT-OFF* */
      hash_foreach_mem (key, value, cm->alg_index_by_name,
      ({
        (void) value;
        rc += vnet_crypto_set_handler2 (key, engine, oct);
      }));
      /* *INDENT-ON* */

      if (rc)
	vlib_cli_output (vm, "failed to set crypto engine!");
    }
  else
    {
      vec_foreach (arg, args)
      {
	rc = vnet_crypto_set_handler2 (arg[0], engine, oct);
	if (rc)
	  {
	    vlib_cli_output (vm, "failed to set engine %s for %s!",
			     engine, arg[0]);
	  }
      }
    }

done:
  vec_free (engine);
  vec_foreach (arg, args) vec_free (arg[0]);
  vec_free (args);
  unformat_free (line_input);
  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (set_crypto_handler_command, static) =
{
  .path = "set crypto handler",
  .short_help = "set crypto handler cipher [cipher2 cipher3 ...] engine"
    " [simple|chained]",
  .function = set_crypto_handler_command_fn,
};
/* *INDENT-ON* */

static u8 *
format_vnet_crypto_async_handlers (u8 * s, va_list * args)
{
  vnet_crypto_async_alg_t alg = va_arg (*args, vnet_crypto_async_alg_t);
  vnet_crypto_main_t *cm = &crypto_main;
  vnet_crypto_async_alg_data_t *d = vec_elt_at_index (cm->async_algs, alg);
  u32 indent = format_get_indent (s);
  int i, first = 1;

  for (i = 0; i < VNET_CRYPTO_ASYNC_OP_N_TYPES; i++)
    {
      vnet_crypto_async_op_data_t *od;
      vnet_crypto_async_op_id_t id = d->op_by_type[i];

      if (id == 0)
	continue;

      od = cm->async_opt_data + id;
      if (first == 0)
	s = format (s, "\n%U", format_white_space, indent);
      s = format (s, "%-16U", format_vnet_crypto_async_op_type, od->type);

      s = format (s, "%U", format_vnet_crypto_engine_candidates, id,
		  od->active_engine_index_async, 0, 1);
      first = 0;
    }
  return s;
}

static clib_error_t *
show_crypto_async_handlers_command_fn (vlib_main_t * vm,
				       unformat_input_t * input,
				       vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  int i;

  if (unformat_user (input, unformat_line_input, line_input))
    unformat_free (line_input);

  vlib_cli_output (vm, "%-28s%-16s%s", "Algo", "Type", "Handler");

  for (i = 0; i < VNET_CRYPTO_N_ASYNC_ALGS; i++)
    vlib_cli_output (vm, "%-28U%U", format_vnet_crypto_async_alg, i,
		     format_vnet_crypto_async_handlers, i);

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_crypto_async_handlers_command, static) =
{
  .path = "show crypto async handlers",
  .short_help = "show crypto async handlers",
  .function = show_crypto_async_handlers_command_fn,
};
/* *INDENT-ON* */


static clib_error_t *
show_crypto_async_status_command_fn (vlib_main_t * vm,
				     unformat_input_t * input,
				     vlib_cli_command_t * cmd)
{
  vnet_crypto_main_t *cm = &crypto_main;
  u32 skip_master = vlib_num_workers () > 0;
  vlib_thread_main_t *tm = vlib_get_thread_main ();
  unformat_input_t _line_input, *line_input = &_line_input;
  int i;

  if (unformat_user (input, unformat_line_input, line_input))
    unformat_free (line_input);

  vlib_cli_output (vm, "Crypto async dispatch mode: %s",
		   cm->dispatch_mode ==
		   VNET_CRYPTO_ASYNC_DISPATCH_POLLING ? "POLLING" :
		   "INTERRUPT");

  for (i = skip_master; i < tm->n_vlib_mains; i++)
    {
      vlib_node_state_t state = vlib_node_get_state (
	vlib_get_main_by_index (i), cm->crypto_node_index);
      if (state == VLIB_NODE_STATE_POLLING)
	vlib_cli_output (vm, "threadId: %-6d POLLING", i);
      if (state == VLIB_NODE_STATE_INTERRUPT)
	vlib_cli_output (vm, "threadId: %-6d INTERRUPT", i);
      if (state == VLIB_NODE_STATE_DISABLED)
	vlib_cli_output (vm, "threadId: %-6d DISABLED", i);
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_crypto_async_status_command, static) =
{
  .path = "show crypto async status",
  .short_help = "show crypto async status",
  .function = show_crypto_async_status_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
set_crypto_async_handler_command_fn (vlib_main_t * vm,
				     unformat_input_t * input,
				     vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  vnet_crypto_main_t *cm = &crypto_main;
  int rc = 0;
  char **args = 0, *s, **arg, *engine = 0;
  int all = 0;
  clib_error_t *error = 0;

  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "all"))
	all = 1;
      else if (unformat (line_input, "%s", &s))
	vec_add1 (args, s);
      else
	{
	  error = clib_error_return (0, "invalid params");
	  goto done;
	}
    }

  if ((vec_len (args) < 2 && !all) || (vec_len (args) == 0 && all))
    {
      error = clib_error_return (0, "missing cipher or engine!");
      goto done;
    }

  engine = vec_elt_at_index (args, vec_len (args) - 1)[0];
  vec_del1 (args, vec_len (args) - 1);

  if (all)
    {
      char *key;
      u8 *value;

      /* *INDENT-OFF* */
      hash_foreach_mem (key, value, cm->async_alg_index_by_name,
      ({
        (void) value;
        rc += vnet_crypto_set_async_handler2 (key, engine);
      }));
      /* *INDENT-ON* */

      if (rc)
	vlib_cli_output (vm, "failed to set crypto engine!");
    }
  else
    {
      vec_foreach (arg, args)
      {
	rc = vnet_crypto_set_async_handler2 (arg[0], engine);
	if (rc)
	  {
	    vlib_cli_output (vm, "failed to set engine %s for %s!",
			     engine, arg[0]);
	  }
      }
    }

done:
  vec_free (engine);
  vec_foreach (arg, args) vec_free (arg[0]);
  vec_free (args);
  unformat_free (line_input);
  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (set_crypto_async_handler_command, static) =
{
  .path = "set crypto async handler",
  .short_help = "set crypto async handler type [type2 type3 ...] engine",
  .function = set_crypto_async_handler_command_fn,
};
/* *INDENT-ON* */

static inline void
print_crypto_async_dispatch_warning ()
{
  clib_warning ("Switching dispatch mode might not work is some situations.");
  clib_warning
    ("Use 'show crypto async status' to verify that the nodes' states were set");
  clib_warning ("and if not, set 'crypto async dispatch' mode again.");
}

static clib_error_t *
set_crypto_async_dispatch_polling_command_fn (vlib_main_t * vm,
					      unformat_input_t * input,
					      vlib_cli_command_t * cmd)
{
  print_crypto_async_dispatch_warning ();
  vnet_crypto_set_async_dispatch_mode (VNET_CRYPTO_ASYNC_DISPATCH_POLLING);
  return 0;
}

static clib_error_t *
set_crypto_async_dispatch_interrupt_command_fn (vlib_main_t * vm,
						unformat_input_t * input,
						vlib_cli_command_t * cmd)
{
  print_crypto_async_dispatch_warning ();
  vnet_crypto_set_async_dispatch_mode (VNET_CRYPTO_ASYNC_DISPATCH_INTERRUPT);
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (set_crypto_async_dispatch_polling_command, static) =
{
  .path = "set crypto async dispatch polling",
  .short_help = "set crypto async dispatch polling|interrupt",
  .function = set_crypto_async_dispatch_polling_command_fn,
};
VLIB_CLI_COMMAND (set_crypto_async_dispatch_interrupt_command, static) =
{
  .path = "set crypto async dispatch interrupt",
  .short_help = "set crypto async dispatch polling|interrupt",
  .function = set_crypto_async_dispatch_interrupt_command_fn,
};
/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
