/*
 * Copyright (c) 2020 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 <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <getopt.h>
#include <assert.h>
#include <vlib/vlib.h>
#include <vlibapi/api_types.h>
#include <vppinfra/hash.h>
#include <vppinfra/cJSON.h>

/* VPP API client includes */
#include <vpp-api/client/vppapiclient.h>

#include <limits.h>
#include "vat2.h"

uword *function_by_name;
bool debug = false;

char *vat2_plugin_path;
static void
vat2_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/lib/" CLIB_TARGET_TRIPLET "/vat2_plugins:"
              "%s/lib/vat2_plugins", path, path);
  vec_add1 (s, 0);
  vat2_plugin_path = (char *) s;
}

void
vac_callback (unsigned char *data, int len)
{
  u16 result_msg_id = ntohs(*((u16 *)data));
  DBG("Received something async: %d\n", result_msg_id);
}

int vat2_load_plugins (char *path, char *filter, int *loaded);

static int
register_function (void)
{
  int loaded;

  vat2_find_plugin_path();
  DBG("Plugin Path %s\n", vat2_plugin_path);
  int rv = vat2_load_plugins(vat2_plugin_path, 0, &loaded);
  DBG("Loaded %u plugins\n", loaded);
  return rv;
}

struct apifuncs_s
{
  cJSON (*f) (cJSON *);
  cJSON (*tojson) (void *);
};

struct apifuncs_s *apifuncs = 0;

void
vat2_register_function (char *name, cJSON (*f) (cJSON *),
			cJSON (*tojson) (void *))
{
  struct apifuncs_s funcs = { .f = f, .tojson = tojson };
  vec_add1 (apifuncs, funcs);
  hash_set_mem (function_by_name, name, vec_len (apifuncs) - 1);
}

static int
vat2_exec_command_by_name (char *msgname, cJSON *o)
{
  uword *p = hash_get_mem (function_by_name, msgname);
  if (!p)
    {
      fprintf (stderr, "No such command %s", msgname);
      return -1;
    }

  cJSON *(*fp) (cJSON *);
  fp = (void *) apifuncs[p[0]].f;
  cJSON *r = (*fp) (o);

  if (r)
    {
      char *output = cJSON_Print (r);
      cJSON_Delete (r);
      printf ("%s\n", output);
      free (output);
    }
  else
    {
      fprintf (stderr, "Call failed: %s\n", msgname);
      return -1;
    }
  return 0;
}

static int
vat2_exec_command (cJSON *o)
{

  cJSON *msg_id_obj = cJSON_GetObjectItem (o, "_msgname");
  if (!msg_id_obj)
    {
      fprintf (stderr, "Missing '_msgname' element!\n");
      return -1;
    }

  char *name = cJSON_GetStringValue (msg_id_obj);
  assert (name);
  return vat2_exec_command_by_name (name, o);
}
static void
print_template (char *msgname)
{
  uword *p = hash_get_mem (function_by_name, msgname);
  if (!p)
    {
      fprintf (stderr, "no such message: %s", msgname);
    }
  cJSON *(*fp) (void *);
  fp = (void *) apifuncs[p[0]].tojson;
  assert (fp);
  void *scratch = malloc (2048);
  memset (scratch, 0, 2048);
  cJSON *t = fp (scratch);
  free (scratch);
  char *output = cJSON_Print (t);
  cJSON_Delete (t);
  printf ("%s\n", output);
  free (output);
}
static void
dump_apis (void)
{
  char *name;
  u32 *i;
  hash_foreach_mem (name, i, function_by_name, ({ printf ("%s\n", name); }));
}

static void
print_help (void)
{
  char *help_string =
    "Usage: vat2 [OPTION] <message-name> <JSON object>\n"
    "Send API message to VPP and print reply\n"
    "\n"
    "-d, --debug       Print additional information\n"
    "-p, --prefix      Specify shared memory prefix to connect to a given VPP "
    "instance\n"
    "-f, --file        File containing a JSON object with the arguments for "
    "the message to send\n"
    "--dump-apis       List all APIs available in VAT2 (might not reflect "
    "running VPP)\n"
    "-t, --template    Print a template JSON object for given API message\n"
    "\n";
  printf ("%s", help_string);
}

int main (int argc, char **argv)
{
  /* Create a heap of 64MB */
  clib_mem_init (0, 64 << 20);
  char *filename = 0, *prefix = 0;
  int index;
  int c;
  opterr = 0;
  cJSON *o = 0;
  int option_index = 0;
  bool dump_api = false;
  bool template = false;
  char *msgname = 0;
  static int debug_flag;
  static struct option long_options[] = {
    { "debug", no_argument, &debug_flag, 1 },
    { "prefix", optional_argument, 0, 'p' },
    { "file", required_argument, 0, 'f' },
    { "dump-apis", no_argument, 0, 0 },
    { "template", no_argument, 0, 't' },
    { 0, 0, 0, 0 }
  };

  while ((c = getopt_long (argc, argv, "hdp:f:", long_options,
			   &option_index)) != -1)
    {
      switch (c)
	{
	case 0:
	  if (option_index == 3)
	    dump_api = true;
	  break;
	case 'd':
	  debug = true;
	  break;
	case 't':
	  template = true;
	  break;
	case 'p':
	  prefix = optarg;
	  break;
	case 'f':
	  filename = optarg;
	  break;
	case '?':
	  print_help ();
	  return 1;
	default:
	  abort ();
	}
    }
  debug = debug_flag == 1 ? true : false;
  DBG ("debug = %d, filename = %s shared memory prefix: %s\n", debug, filename,
       prefix);

  for (index = optind; index < argc; index++)
    DBG ("Non-option argument %s\n", argv[index]);

  index = optind;

  if (argc > index + 2)
    {
      fprintf (stderr, "%s: Too many arguments\n", argv[0]);
      exit (-1);
    }

  /* Load plugins */
  function_by_name = hash_create_string (0, sizeof (uword));
  int res = register_function();
  if (res < 0) {
    fprintf(stderr, "%s: loading plugins failed\n", argv[0]);
    exit(-1);
  }

  if (template)
    {
      print_template (argv[index]);
      exit (0);
    }

  if (dump_api)
    {
      dump_apis ();
      exit (0);
    }

  /* Read message arguments from command line */
  if (argc >= (index + 1))
    {
      msgname = argv[index];
    }
  if (argc == (index + 2)) {
    o = cJSON_Parse(argv[index+1]);
    if (!o) {
      fprintf(stderr, "%s: Failed parsing JSON input: %s\n", argv[0], cJSON_GetErrorPtr());
      exit(-1);
    }
  }

  /* Read message from file */
  if (filename) {
      if (argc > index)
	{
	  fprintf (stderr, "%s: Superfluous arguments when filename given\n",
		   argv[0]);
	  exit (-1);
	}

    FILE *f = fopen(filename, "r");
    size_t chunksize, bufsize;
    size_t n_read = 0;
    size_t n;

    if (!f) {
      fprintf(stderr, "%s: can't open file: %s\n", argv[0], filename);
      exit(-1);
    }
    chunksize = bufsize = 1024;
    char *buf = malloc(bufsize);
    while ((n = fread (buf + n_read, 1, chunksize, f)))
      {
	n_read += n;
	if (n == chunksize)
	  {
	    bufsize += chunksize;
	    buf = realloc (buf, bufsize);
	  }
      }
    fclose(f);
    if (n_read) {
      o = cJSON_Parse(buf);
      free(buf);
      if (!o) {
        fprintf(stderr, "%s: Failed parsing JSON input: %s\n", argv[0], cJSON_GetErrorPtr());
        exit(-1);
      }
    }
  }

  if (!msgname && !filename)
    {
      print_help ();
      exit (-1);
    }

  if (vac_connect ("vat2", prefix, 0, 1024))
    {
      fprintf (stderr, "Failed connecting to VPP\n");
      exit (-1);
    }

  if (msgname)
    {
      vat2_exec_command_by_name (msgname, o);
    }
  else
    {
      if (cJSON_IsArray (o))
	{
	  size_t size = cJSON_GetArraySize (o);
	  for (int i = 0; i < size; i++)
	    vat2_exec_command (cJSON_GetArrayItem (o, i));
	}
    }
  cJSON_Delete (o);
  vac_disconnect();
  exit (0);

}
