/*
 * 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.
 */
#include "vat.h"
#include <dlfcn.h>
#include "plugin.h"
#include <signal.h>
#include <limits.h>

vat_main_t vat_main;

#include <vlibapi/api_helper_macros.h>

void
vat_suspend (vlib_main_t * vm, f64 interval)
{
  /* do nothing in the standalone version, just return */
}

int
connect_to_vpe (char *name)
{
  vat_main_t *vam = &vat_main;
  api_main_t *am = vlibapi_get_main ();

  if (vl_client_connect_to_vlib ("/vpe-api", name, 32) < 0)
    return -1;

  vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
  vam->my_client_index = am->my_client_index;

  return 0;
}


vlib_global_main_t vlib_global_main;

void
vlib_cli_output (struct vlib_main_t *vm, char *fmt, ...)
{
  clib_warning ("BUG");
}

static u8 *
format_api_error (u8 * s, va_list * args)
{
  vat_main_t *vam = va_arg (*args, vat_main_t *);
  i32 error = va_arg (*args, u32);
  uword *p;

  p = hash_get (vam->error_string_by_error_number, -error);

  if (p)
    s = format (s, "%s", p[0]);
  else
    s = format (s, "%d", error);
  return s;
}

void
do_one_file (vat_main_t * vam)
{
  int rv;
  int (*fp) (vat_main_t * vam);
  int arg_len;
  unformat_input_t _input;
  u8 *cmdp, *argsp;
  uword *p;
  u8 *this_cmd = 0;

  vam->input = &_input;

  /* Used by the "quit" command handler */
  if (setjmp (vam->jump_buf) != 0)
    return;

  vam->jump_buf_set = 1;

  while (1)
    {
      if (vam->ifp == stdin)
	{
	  if (vam->exec_mode == 0)
	    rv = write (1, "vat# ", 5);
	  else
	    rv = write (1, "exec# ", 6);
	}

      vec_set_len (vam->inbuf, 4096);

      if (vam->do_exit ||
	  fgets ((char *) vam->inbuf, vec_len (vam->inbuf), vam->ifp) == 0)
	break;

      vam->input_line_number++;

      vec_free (this_cmd);

      this_cmd =
	(u8 *) clib_macro_eval (&vam->macro_main, (i8 *) vam->inbuf,
				1 /* complain */ ,
				0 /* level */ ,
				8 /* max_level */ );

      if (vam->exec_mode == 0)
	{
	  /* Split input into cmd + args */
	  cmdp = this_cmd;

	  while (cmdp < (this_cmd + vec_len (this_cmd)))
	    {
	      if (*cmdp == ' ' || *cmdp == '\t' || *cmdp == '\n')
		{
		  cmdp++;
		}
	      else
		break;
	    }
	  argsp = cmdp;
	  while (argsp < (this_cmd + vec_len (this_cmd)))
	    {
	      if (*argsp != ' ' && *argsp != '\t' && *argsp != '\n')
		{
		  argsp++;
		}
	      else
		break;
	    }
	  *argsp++ = 0;
	  while (argsp < (this_cmd + vec_len (this_cmd)))
	    {
	      if (*argsp == ' ' || *argsp == '\t' || *argsp == '\n')
		{
		  argsp++;
		}
	      else
		break;
	    }


	  /* Blank input line? */
	  if (*cmdp == 0)
	    continue;

	  p = hash_get_mem (vam->function_by_name, cmdp);
	  if (p == 0)
	    {
	      errmsg ("'%s': function not found\n", cmdp);
	      continue;
	    }

	  arg_len = strlen ((char *) argsp);

	  unformat_init_string (vam->input, (char *) argsp, arg_len);
	  fp = (void *) p[0];
	}
      else
	{
	  unformat_init_string (vam->input, (char *) this_cmd,
				strlen ((char *) this_cmd));
	  cmdp = this_cmd;
	  fp = exec;
	}

      rv = (*fp) (vam);
      if (rv < 0)
	errmsg ("%s error: %U\n", cmdp, format_api_error, vam, rv);
      unformat_free (vam->input);

      if (vam->regenerate_interface_table)
	{
	  vam->regenerate_interface_table = 0;
	  vam->api_sw_interface_dump (vam);
	}

      /* Hack to pick up new client index after memfd_segment_create pivot */
      if (vam->client_index_invalid)
	{
	  vat_main_t *vam = &vat_main;
	  api_main_t *am = vlibapi_get_main ();

	  vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
	  vam->my_client_index = am->my_client_index;
	  vam->client_index_invalid = 0;
	}
    }
}

static void
init_error_string_table (vat_main_t * vam)
{

  vam->error_string_by_error_number = hash_create (0, sizeof (uword));

#define _(n,v,s) hash_set (vam->error_string_by_error_number, -v, s);
  foreach_vnet_api_error;
#undef _

  hash_set (vam->error_string_by_error_number, 99, "Misc");
}

static i8 *
eval_current_file (clib_macro_main_t * mm, i32 complain)
{
  vat_main_t *vam = &vat_main;
  return ((i8 *) format (0, "%s%c", vam->current_file, 0));
}

static i8 *
eval_current_line (clib_macro_main_t * mm, i32 complain)
{
  vat_main_t *vam = &vat_main;
  return ((i8 *) format (0, "%d%c", vam->input_line_number, 0));
}

static void
signal_handler (int signum, siginfo_t * si, ucontext_t * uc)
{
  vat_main_t *vam = &vat_main;

  switch (signum)
    {
      /* these (caught) signals cause the application to exit */
    case SIGINT:
    case SIGTERM:
      if (vam->jump_buf_set)
	{
	  vam->do_exit = 1;
	  return;
	}

      /* FALLTHROUGH on purpose */

    default:
      break;
    }

  _exit (1);
}

static void
setup_signal_handlers (void)
{
  uword i;
  struct sigaction sa;

  for (i = 1; i < 32; i++)
    {
      clib_memset (&sa, 0, sizeof (sa));
      sa.sa_sigaction = (void *) signal_handler;
      sa.sa_flags = SA_SIGINFO;

      switch (i)
	{
	  /* these signals take the default action */
	case SIGABRT:
	case SIGKILL:
	case SIGCONT:
	case SIGSTOP:
	case SIGUSR1:
	case SIGUSR2:
	case SIGPROF:
	  continue;

	  /* ignore SIGPIPE, SIGCHLD */
	case SIGPIPE:
	case SIGCHLD:
	case SIGWINCH:
	  sa.sa_sigaction = (void *) SIG_IGN;
	  break;

	  /* catch and handle all other signals */
	default:
	  break;
	}

      if (sigaction (i, &sa, 0) < 0)
	clib_unix_warning ("sigaction %U", format_signal, i);
    }
}

static void
vat_find_plugin_path ()
{
  char *p, path[PATH_MAX];
  int rv;
  u8 *s;

  /* find executable path */
  if ((rv = readlink ("/proc/self/exe", path, PATH_MAX - 1)) == -1)
    return;

  /* readlink doesn't provide null termination */
  path[rv] = 0;

  /* strip filename */
  if ((p = strrchr (path, '/')) == 0)
    return;
  *p = 0;

  /* strip bin/ */
  if ((p = strrchr (path, '/')) == 0)
    return;
  *p = 0;

  s = format (0, "%s/" CLIB_LIB_DIR "/vpp_api_test_plugins", path, path);
  vec_add1 (s, 0);
  vat_plugin_path = (char *) s;
}

static void
load_features (void)
{
  vat_registered_features_t *f;
  vat_main_t *vam = &vat_main;
  clib_error_t *error;

  f = vam->feature_function_registrations;

  while (f)
    {
      error = f->function (vam);
      if (error)
	{
	  clib_warning ("INIT FAILED");
	}
      f = f->next;
    }
}

static inline clib_error_t *
call_init_exit_functions_internal (vlib_main_t *vm,
				   _vlib_init_function_list_elt_t **headp,
				   int call_once, int do_sort, int is_global)
{
  vlib_global_main_t *vgm = vlib_get_global_main ();
  clib_error_t *error = 0;
  _vlib_init_function_list_elt_t *i;

  ASSERT (is_global == 1);

#if 0
  /* Not worth copying the topological sort code */
  if (do_sort && (error = vlib_sort_init_exit_functions (headp)))
    return (error);
#endif

  i = *headp;
  while (i)
    {
      if (call_once && !hash_get (vgm->init_functions_called, i->f))
	{
	  if (call_once)
	    hash_set1 (vgm->init_functions_called, i->f);
	  error = i->f (vm);
	  if (error)
	    return error;
	}
      i = i->next_init_function;
    }
  return error;
}

clib_error_t *
vlib_call_init_exit_functions (vlib_main_t *vm,
			       _vlib_init_function_list_elt_t **headp,
			       int call_once, int is_global)
{
  return call_init_exit_functions_internal (vm, headp, call_once,
					    1 /* do_sort */, is_global);
}

static void
vat_register_interface_dump (vat_main_t *vam)
{
  void *handle;
  plugin_info_t *pi;

  vec_foreach (pi, vat_plugin_main.plugin_info)
    {
      handle = dlsym (pi->handle, "api_sw_interface_dump");
      if (handle)
	{
	  vam->api_sw_interface_dump = handle;
	  break;
	}
    }

  if (!vam->api_sw_interface_dump)
    {
      fformat (stderr,
	       "sw_interface_dump not found in interface_test plugin!\n");
      exit (1);
    }
}

int
main (int argc, char **argv)
{
  vlib_global_main_t *vgm = vlib_get_global_main ();
  vat_main_t *vam = &vat_main;
  unformat_input_t _argv, *a = &_argv;
  u8 **input_files = 0;
  u8 *output_file = 0;
  u8 *chroot_prefix;
  u8 *this_input_file;
  u8 interactive = 1;
  u8 json_output = 0;
  int i;
  f64 timeout;
  clib_error_t *error;
  vlib_main_t *vm;

  clib_mem_init_thread_safe (0, 128 << 20);
  vlib_main_init ();
  vm = vlib_get_first_main ();

  clib_macro_init (&vam->macro_main);
  clib_macro_add_builtin (&vam->macro_main, "current_file",
			  eval_current_file);
  clib_macro_add_builtin (&vam->macro_main, "current_line",
			  eval_current_line);

  init_error_string_table (vam);
  vec_validate (vam->cmd_reply, 0);
  vec_reset_length (vam->cmd_reply);

  vat_find_plugin_path ();

  unformat_init_command_line (a, argv);

  while (unformat_check_input (a) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (a, "in %s", &this_input_file))
	vec_add1 (input_files, this_input_file);
      else if (unformat (a, "out %s", &output_file))
	;
      else if (unformat (a, "script"))
	interactive = 0;
      else if (unformat (a, "json"))
	json_output = 1;
      else if (unformat (a, "socket-name %s", &vam->socket_name))
	;
      else if (unformat (a, "default-socket"))
	{
	  vam->socket_name = format (0, "%s%c", API_SOCKET_FILE, 0);
	}
      else if (unformat (a, "plugin_path %s", (u8 *) & vat_plugin_path))
	vec_add1 (vat_plugin_path, 0);
      else if (unformat (a, "plugin_name_filter %s",
			 (u8 *) & vat_plugin_name_filter))
	vec_add1 (vat_plugin_name_filter, 0);
      else if (unformat (a, "chroot prefix %s", &chroot_prefix))
	{
	  vl_set_memory_root_path ((char *) chroot_prefix);
	}
      else
	{
	  fformat
	    (stderr,
	     "%s: usage [in <f1> ... in <fn>] [out <fn>] [script] [json]\n"
	     "[plugin_path <path>][default-socket][socket-name <name>]\n"
	     "[plugin_name_filter <filter>][chroot prefix <path>]\n",
	     argv[0]);
	  exit (1);
	}
    }

  if (output_file)
    vam->ofp = fopen ((char *) output_file, "w");
  else
    vam->ofp = stdout;

  if (vam->ofp == NULL)
    {
      fformat (stderr, "Couldn't open output file %s\n",
	       output_file ? (char *) output_file : "stdout");
      exit (1);
    }

  clib_time_init (&vam->clib_time);

  vat_api_hookup (vam);
  vat_plugin_api_reference ();

  setup_signal_handlers ();

  if (vam->socket_name && vat_socket_connect (vam))
    fformat (stderr, "WARNING: socket connection failed");

  if ((!vam->socket_client_main || vam->socket_client_main->socket_fd == 0)
      && connect_to_vpe ("vpp_api_test") < 0)
    {
      svm_region_exit ();
      fformat (stderr, "Couldn't connect to vpe, exiting...\n");
      exit (1);
    }

  vam->json_output = json_output;

  vec_validate (vam->inbuf, 4096);

  load_features ();

  vam->current_file = (u8 *) "plugin-init";
  vat_plugin_init (vam);

  vat_register_interface_dump (vam);

  if (!json_output)
    vam->api_sw_interface_dump (vam);

  /* Set up the init function hash table */
  vgm->init_functions_called = hash_create (0, 0);

  /* Execute plugin init and api_init functions */
  error = vlib_call_init_exit_functions (vm, &vgm->init_function_registrations,
					 1 /* call once */, 1 /* is_global*/);

  if (error)
    clib_error_report (error);

  error =
    vlib_call_init_exit_functions (vm, &vgm->api_init_function_registrations,
				   1 /* call_once */, 1 /* is_global */);

  if (error)
    clib_error_report (error);

  for (i = 0; i < vec_len (input_files); i++)
    {
      vam->ifp = fopen ((char *) input_files[i], "r");
      if (vam->ifp == NULL)
	{
	  fformat (stderr, "Couldn't open input file %s\n", input_files[i]);
	  continue;
	}
      vam->current_file = input_files[i];
      vam->input_line_number = 0;
      do_one_file (vam);
      fclose (vam->ifp);
    }

  if (output_file)
    fclose (vam->ofp);

  if (interactive)
    {
      vam->ifp = stdin;
      vam->ofp = stdout;
      vam->current_file = (u8 *) "interactive";
      do_one_file (vam);
      fclose (vam->ifp);
    }

  /*
   * Particularly when running a script, don't be in a hurry to leave.
   * A reply message queued to this process will end up constipating
   * the allocation rings.
   */
  timeout = vat_time_now (vam) + 2.0;
  while (vam->result_ready == 0 && vat_time_now (vam) < timeout)
    ;

  if (vat_time_now (vam) > timeout)
    clib_warning ("BUG: message reply spin-wait timeout");

  vl_client_disconnect_from_vlib ();
  exit (0);
}

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