/*
 *------------------------------------------------------------------
 * test.c -- VPP API/Stats tests
 * 
 * Copyright (c) 2016 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 <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netdb.h>


#include <vnet/vnet.h>
#include <vlib/vlib.h>
#include <vlib/unix/unix.h>
#include <vlibapi/api.h>
#include <vppinfra/time.h>
#include <vpp/api/vpe_msg_enum.h>
#include <signal.h>
#include "vppapiclient.h"
#include "stat_client.h"

#define vl_typedefs             /* define message structures */
#include <vpp/api/vpe_all_api_h.h> 
#undef vl_typedefs

volatile int sigterm_received = 0;
volatile u32 result_ready;
volatile u16 result_msg_id;

/* M_NOALLOC: construct, but don't yet send a message */

#define M_NOALLOC(T,t)                          \
  do {						\
    result_ready = 0;                           \
    clib_memset (mp, 0, sizeof (*mp));		\
    mp->_vl_msg_id = ntohs (VL_API_##T);	\
    mp->client_index = am->my_client_index;	\
  } while(0);



void
wrap_vac_callback (unsigned char *data, int len)
{
  result_ready = 1;
  result_msg_id = ntohs(*((u16 *)data));
}

static void
test_connect ()
{
  static int i;
  int rv = vac_connect("vac_client", NULL, wrap_vac_callback, 32 /* rx queue-length*/);
  if (rv != 0) {
    printf("Connect failed: %d\n", rv);
    exit(rv);
  }
  printf(".");
  vac_disconnect();
  i++;
}

static void
test_messages (void)
{
  api_main_t * am = vlibapi_get_main();
  vl_api_show_version_t message;
  vl_api_show_version_t *mp;
  int async = 1;

  int rv = vac_connect("vac_client", NULL, wrap_vac_callback, 32 /* rx queue-length*/);
  if (rv != 0) {
    printf("Connect failed: %d\n", rv);
    exit(rv);
  }

  double timestamp_start = unix_time_now_nsec() * 1e-6;
 
  /*
   * Test vpe_api_write and vpe_api_read to send and recv message for an
   * API 
   */
  int i;
  long int no_msgs = 10000;
  mp = &message;

  for (i = 0; i < no_msgs; i++) {
    /* Construct the API message */
    M_NOALLOC(SHOW_VERSION, show_version);
    vac_write((char *)mp, sizeof(*mp));
#ifndef __COVERITY__
    /* As given, async is always 1. Shut up Coverity about it */
    if (!async)
      while (result_ready == 0);
#endif
  }
  if (async) {
    vl_api_control_ping_t control;
    vl_api_control_ping_t *mp;
    mp = &control;
    M_NOALLOC(CONTROL_PING, control_ping);
    vac_write((char *)mp, sizeof(*mp));

    while (result_msg_id != VL_API_CONTROL_PING_REPLY);
  }

  double timestamp_end = unix_time_now_nsec() * 1e-6;
  printf("\nTook %.2f msec, %.0f msgs/msec \n", (timestamp_end - timestamp_start),
	 no_msgs/(timestamp_end - timestamp_start));
  printf("Exiting...\n");
  vac_disconnect();
}

static void
test_stats (void)
{
  clib_mem_trace_enable_disable(1);
  clib_mem_trace (1);

  int rv = stat_segment_connect (STAT_SEGMENT_SOCKET_FILE);
  assert(rv == 0);

  u32 *dir;
  int i, j, k;
  stat_segment_data_t *res;
  u8 **pattern = 0;
  vec_add1(pattern, (u8 *)"/if/names");
  vec_add1(pattern, (u8 *)"/err");

  dir = stat_segment_ls ((u8 **)pattern);

  res = stat_segment_dump (dir);
  for (i = 0; i < vec_len (res); i++) {
    switch (res[i].type) {
    case STAT_DIR_TYPE_NAME_VECTOR:
      if (res[i].name_vector == 0)
	continue;
      for (k = 0; k < vec_len (res[i].name_vector); k++)
	if (res[i].name_vector[k])
	  fformat (stdout, "[%d]: %s %s\n", k, res[i].name_vector[k],
		   res[i].name);
      break;
    case STAT_DIR_TYPE_ERROR_INDEX:
      for (j = 0; j < vec_len (res[i].error_vector); j++)
	fformat (stdout, "%llu %s\n", res[i].error_vector[j],
		 res[i].name);
      break;
    default:
      assert(0);
    }
  }
  stat_segment_data_free (res);
  stat_segment_disconnect();

  vec_free(pattern);
  vec_free(dir);

  (void) clib_mem_trace_enable_disable (0);
  u8 *leak_report = format (0, "%U", format_clib_mem_heap, 0,
                            1 /* verbose, i.e. print leaks */ );
  printf("%s", leak_report);
  vec_free (leak_report);
  clib_mem_trace (0);
}

int main (int argc, char ** argv)
{
  clib_mem_init (0, 3ULL << 30);
  test_stats();

  int i;

  for (i = 0; i < 1000; i++) {
    test_connect();
  }
  test_messages();
  exit (0);
}
