/*
 * 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_handlers[id])
	    {
	      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_mains[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:
 */
