/*
 *------------------------------------------------------------------
 * stat_client.c - Library for access to VPP statistics segment
 *
 * Copyright (c) 2018 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 <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <regex.h>
#include <assert.h>
#include <vppinfra/vec.h>
#include <vppinfra/lock.h>
#include <stdatomic.h>
#include <vpp/stats/stat_segment.h>
#include <vpp-api/client/stat_client.h>

stat_client_main_t stat_client_main;

stat_client_main_t *
stat_client_get (void)
{
  stat_client_main_t *sm;
  sm = (stat_client_main_t *) malloc (sizeof (stat_client_main_t));
  clib_memset (sm, 0, sizeof (stat_client_main_t));
  return sm;
}

void
stat_client_free (stat_client_main_t * sm)
{
  free (sm);
}

static int
recv_fd (int sock)
{
  struct msghdr msg = { 0 };
  struct cmsghdr *cmsg;
  int fd = -1;
  char iobuf[1];
  struct iovec io = {.iov_base = iobuf,.iov_len = sizeof (iobuf) };
  union
  {
    char buf[CMSG_SPACE (sizeof (fd))];
    struct cmsghdr align;
  } u;
  msg.msg_iov = &io;
  msg.msg_iovlen = 1;
  msg.msg_control = u.buf;
  msg.msg_controllen = sizeof (u.buf);

  ssize_t size;
  if ((size = recvmsg (sock, &msg, 0)) < 0)
    {
      perror ("recvmsg failed");
      return -1;
    }
  cmsg = CMSG_FIRSTHDR (&msg);
  if (cmsg && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
    {
      memmove (&fd, CMSG_DATA (cmsg), sizeof (fd));
    }
  return fd;
}

static stat_segment_directory_entry_t *
get_stat_vector_r (stat_client_main_t * sm)
{
  ASSERT (sm->shared_header);
  return stat_segment_adjust (sm,
			      (void *) sm->shared_header->directory_vector);
}

int
stat_segment_connect_r (const char *socket_name, stat_client_main_t * sm)
{
  int mfd = -1;
  int sock;

  clib_memset (sm, 0, sizeof (*sm));
  if ((sock = socket (AF_UNIX, SOCK_SEQPACKET, 0)) < 0)
    {
      perror ("Stat client couldn't open socket");
      return -1;
    }

  struct sockaddr_un un = { 0 };
  un.sun_family = AF_UNIX;
  strncpy ((char *) un.sun_path, socket_name, sizeof (un.sun_path) - 1);
  if (connect (sock, (struct sockaddr *) &un, sizeof (struct sockaddr_un)) <
      0)
    {
      close (sock);
      return -2;
    }

  if ((mfd = recv_fd (sock)) < 0)
    {
      close (sock);
      fprintf (stderr, "Receiving file descriptor failed\n");
      return -3;
    }
  close (sock);

  /* mmap shared memory segment. */
  void *memaddr;
  struct stat st = { 0 };

  if (fstat (mfd, &st) == -1)
    {
      close (mfd);
      perror ("mmap fstat failed");
      return -4;
    }
  if ((memaddr =
       mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, mfd, 0)) == MAP_FAILED)
    {
      close (mfd);
      perror ("mmap map failed");
      return -5;
    }

  close (mfd);
  sm->memory_size = st.st_size;
  sm->shared_header = memaddr;
  sm->directory_vector =
    stat_segment_adjust (sm, (void *) sm->shared_header->directory_vector);

  return 0;
}

int
stat_segment_connect (const char *socket_name)
{
  stat_client_main_t *sm = &stat_client_main;
  return stat_segment_connect_r (socket_name, sm);
}

void
stat_segment_disconnect_r (stat_client_main_t * sm)
{
  munmap (sm->shared_header, sm->memory_size);
  return;
}

void
stat_segment_disconnect (void)
{
  stat_client_main_t *sm = &stat_client_main;
  return stat_segment_disconnect_r (sm);
}

double
stat_segment_heartbeat_r (stat_client_main_t * sm)
{
  stat_segment_access_t sa;
  stat_segment_directory_entry_t *ep;

  /* Has directory been update? */
  if (sm->shared_header->epoch != sm->current_epoch)
    return 0;
  if (stat_segment_access_start (&sa, sm))
    return 0;
  ep = vec_elt_at_index (sm->directory_vector, STAT_COUNTER_HEARTBEAT);
  if (!stat_segment_access_end (&sa, sm))
    return 0.0;
  return ep->value;
}

double
stat_segment_heartbeat (void)
{
  stat_client_main_t *sm = &stat_client_main;
  return stat_segment_heartbeat_r (sm);
}

static stat_segment_data_t
copy_data (stat_segment_directory_entry_t * ep, stat_client_main_t * sm)
{
  stat_segment_data_t result = { 0 };
  int i;
  vlib_counter_t **combined_c;	/* Combined counter */
  counter_t **simple_c;		/* Simple counter */
  uint64_t *error_vector;

  assert (sm->shared_header);

  result.type = ep->type;
  result.name = strdup (ep->name);
  switch (ep->type)
    {
    case STAT_DIR_TYPE_SCALAR_INDEX:
      result.scalar_value = ep->value;
      break;

    case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
      simple_c = stat_segment_adjust (sm, ep->data);
      result.simple_counter_vec = vec_dup (simple_c);
      for (i = 0; i < vec_len (simple_c); i++)
	{
	  counter_t *cb = stat_segment_adjust (sm, simple_c[i]);
	  result.simple_counter_vec[i] = vec_dup (cb);
	}
      break;

    case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
      combined_c = stat_segment_adjust (sm, ep->data);
      result.combined_counter_vec = vec_dup (combined_c);
      for (i = 0; i < vec_len (combined_c); i++)
	{
	  vlib_counter_t *cb = stat_segment_adjust (sm, combined_c[i]);
	  result.combined_counter_vec[i] = vec_dup (cb);
	}
      break;

    case STAT_DIR_TYPE_ERROR_INDEX:
      /* Gather errors from all threads into a vector */
      error_vector =
	stat_segment_adjust (sm, (void *) sm->shared_header->error_vector);
      vec_validate (result.error_vector, vec_len (error_vector) - 1);
      for (i = 0; i < vec_len (error_vector); i++)
	{
	  counter_t *cb = stat_segment_adjust (sm, (void *) error_vector[i]);
	  result.error_vector[i] = cb[ep->index];
	}
      break;

    case STAT_DIR_TYPE_NAME_VECTOR:
      {
	uint8_t **name_vector = stat_segment_adjust (sm, ep->data);
	result.name_vector = vec_dup (name_vector);
	for (i = 0; i < vec_len (name_vector); i++)
	  {
	    u8 *name = stat_segment_adjust (sm, name_vector[i]);
	    result.name_vector[i] = vec_dup (name);
	  }
      }
      break;

    case STAT_DIR_TYPE_EMPTY:
      break;

    default:
      fprintf (stderr, "Unknown type: %d\n", ep->type);
    }
  return result;
}

void
stat_segment_data_free (stat_segment_data_t * res)
{
  int i, j;
  for (i = 0; i < vec_len (res); i++)
    {
      switch (res[i].type)
	{
	case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
	  for (j = 0; j < vec_len (res[i].simple_counter_vec); j++)
	    vec_free (res[i].simple_counter_vec[j]);
	  vec_free (res[i].simple_counter_vec);
	  break;
	case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
	  for (j = 0; j < vec_len (res[i].combined_counter_vec); j++)
	    vec_free (res[i].combined_counter_vec[j]);
	  vec_free (res[i].combined_counter_vec);
	  break;
	case STAT_DIR_TYPE_NAME_VECTOR:
	  for (j = 0; j < vec_len (res[i].name_vector); j++)
	    vec_free (res[i].name_vector[j]);
	  vec_free (res[i].name_vector);
	  break;
	case STAT_DIR_TYPE_ERROR_INDEX:
	  vec_free (res[i].error_vector);
	  break;
	default:
	  assert (0);
	}
      free (res[i].name);
    }
  vec_free (res);
}

uint32_t *
stat_segment_ls_r (uint8_t ** patterns, stat_client_main_t * sm)
{
  stat_segment_access_t sa;

  uint32_t *dir = 0;
  regex_t regex[vec_len (patterns)];

  int i, j;
  for (i = 0; i < vec_len (patterns); i++)
    {
      int rv = regcomp (&regex[i], (const char *) patterns[i], 0);
      if (rv)
	{
	  fprintf (stderr, "Could not compile regex %s\n", patterns[i]);
	  return dir;
	}
    }

  if (stat_segment_access_start (&sa, sm))
    return 0;

  stat_segment_directory_entry_t *counter_vec = get_stat_vector_r (sm);
  for (j = 0; j < vec_len (counter_vec); j++)
    {
      for (i = 0; i < vec_len (patterns); i++)
	{
	  int rv = regexec (&regex[i], counter_vec[j].name, 0, NULL, 0);
	  if (rv == 0)
	    {
	      vec_add1 (dir, j);
	      break;
	    }
	}
      if (vec_len (patterns) == 0)
	vec_add1 (dir, j);
    }

  for (i = 0; i < vec_len (patterns); i++)
    regfree (&regex[i]);

  if (!stat_segment_access_end (&sa, sm))
    {
      /* Failed, clean up */
      vec_free (dir);
      return 0;

    }

  /* Update last version */
  sm->current_epoch = sa.epoch;
  return dir;
}

uint32_t *
stat_segment_ls (uint8_t ** patterns)
{
  stat_client_main_t *sm = &stat_client_main;
  return stat_segment_ls_r ((uint8_t **) patterns, sm);
}

stat_segment_data_t *
stat_segment_dump_r (uint32_t * stats, stat_client_main_t * sm)
{
  int i;
  stat_segment_directory_entry_t *ep;
  stat_segment_data_t *res = 0;
  stat_segment_access_t sa;

  /* Has directory been update? */
  if (sm->shared_header->epoch != sm->current_epoch)
    return 0;

  if (stat_segment_access_start (&sa, sm))
    return 0;

  for (i = 0; i < vec_len (stats); i++)
    {
      /* Collect counter */
      ep = vec_elt_at_index (sm->directory_vector, stats[i]);
      vec_add1 (res, copy_data (ep, sm));
    }

  if (stat_segment_access_end (&sa, sm))
    return res;

  fprintf (stderr, "Epoch changed while reading, invalid results\n");
  // TODO increase counter
  return 0;
}

stat_segment_data_t *
stat_segment_dump (uint32_t * stats)
{
  stat_client_main_t *sm = &stat_client_main;
  return stat_segment_dump_r (stats, sm);
}

/* Wrapper for accessing vectors from other languages */
int
stat_segment_vec_len (void *vec)
{
  return vec_len (vec);
}

void
stat_segment_vec_free (void *vec)
{
  vec_free (vec);
}

/* Create a vector from a string (or add to existing) */
uint8_t **
stat_segment_string_vector (uint8_t ** string_vector, const char *string)
{
  uint8_t *name = 0;
  size_t len = strlen (string);

  vec_validate_init_c_string (name, string, len);
  vec_add1 (string_vector, name);
  return string_vector;
}

stat_segment_data_t *
stat_segment_dump_entry_r (uint32_t index, stat_client_main_t * sm)
{
  stat_segment_directory_entry_t *ep;
  stat_segment_data_t *res = 0;
  stat_segment_access_t sa;

  if (stat_segment_access_start (&sa, sm))
    return 0;

  /* Collect counter */
  ep = vec_elt_at_index (sm->directory_vector, index);
  vec_add1 (res, copy_data (ep, sm));

  if (stat_segment_access_end (&sa, sm))
    return res;
  return 0;
}

stat_segment_data_t *
stat_segment_dump_entry (uint32_t index)
{
  stat_client_main_t *sm = &stat_client_main;
  return stat_segment_dump_entry_r (index, sm);
}

char *
stat_segment_index_to_name_r (uint32_t index, stat_client_main_t * sm)
{
  stat_segment_directory_entry_t *ep;
  stat_segment_access_t sa;
  stat_segment_directory_entry_t *vec;

  /* Has directory been update? */
  if (sm->shared_header->epoch != sm->current_epoch)
    return 0;
  if (stat_segment_access_start (&sa, sm))
    return 0;
  vec = get_stat_vector_r (sm);
  ep = vec_elt_at_index (vec, index);
  if (!stat_segment_access_end (&sa, sm))
    return 0;
  return strdup (ep->name);
}

char *
stat_segment_index_to_name (uint32_t index)
{
  stat_client_main_t *sm = &stat_client_main;
  return stat_segment_index_to_name_r (index, sm);
}

uint64_t
stat_segment_version_r (stat_client_main_t * sm)
{
  ASSERT (sm->shared_header);
  return sm->shared_header->version;
}

uint64_t
stat_segment_version (void)
{
  stat_client_main_t *sm = &stat_client_main;
  return stat_segment_version_r (sm);
}

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