/* 
 * Copyright (c) 2012 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 <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <vppinfra/clib.h>
#include <vppinfra/vec.h>
#include <vppinfra/hash.h>
#include <vppinfra/bitmap.h>
#include <vppinfra/fifo.h>
#include <vppinfra/time.h>
#include <vppinfra/mheap.h>
#include <vppinfra/heap.h>
#include <vppinfra/pool.h>
#include <vppinfra/format.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>

#include <vlib/vlib.h>
#include <vlib/unix/unix.h>
#include <vnet/api_errno.h>

#include <svmdb.h>

typedef struct {
  svmdb_client_t *svmdb_client;
  f64 *vector_rate_ptr;
  f64 *input_rate_ptr;
  f64 *sig_error_rate_ptr;
  pid_t *vpef_pid_ptr;
  u64 last_sig_errors;
  u64 current_sig_errors;
  uword * sig_error_bitmap;
  vlib_main_t *vlib_main;
  vlib_main_t ** my_vlib_mains;

} gmon_main_t;

#if DPDK == 0
static inline u64 vnet_get_aggregate_rx_packets (void)
{ return 0; }
#else
#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vnet/devices/dpdk/dpdk.h>
#endif

gmon_main_t gmon_main;

static u64 get_significant_errors(gmon_main_t * gm)
{
  vlib_main_t * this_vlib_main;
  vlib_error_main_t * em;
  uword code;
  int vm_index;
  u64 significant_errors = 0;

  clib_bitmap_foreach (code, gm->sig_error_bitmap,
  ({
    for (vm_index = 0; vm_index < vec_len (gm->my_vlib_mains); vm_index++)
      {
        this_vlib_main = gm->my_vlib_mains[vm_index];
        em = &this_vlib_main->error_main;
        significant_errors += em->counters[code] -
          ((vec_len(em->counters_last_clear) > code) ?
           em->counters_last_clear[code] : 0);
      }
  }));

  return (significant_errors);
}

static clib_error_t *
publish_pid (vlib_main_t *vm)
{
  gmon_main_t *gm = &gmon_main;

  *gm->vpef_pid_ptr = getpid();

  return 0;
}
VLIB_API_INIT_FUNCTION(publish_pid);


static uword
gmon_process (vlib_main_t * vm,
              vlib_node_runtime_t * rt,
              vlib_frame_t * f)
{
    f64 vector_rate;
    u64 input_packets, last_input_packets, new_sig_errors;
    f64 last_runtime, dt, now;
    gmon_main_t *gm = &gmon_main;
    int i;

    last_runtime = 0.0; 
    last_input_packets = 0;
	      
    last_runtime = 0.0;
    last_input_packets = 0;

    /* Initial wait for the world to settle down */
    vlib_process_suspend (vm, 5.0);

    if (vec_len(vlib_mains) == 0)
      vec_add1(gm->my_vlib_mains, &vlib_global_main);
    else
      {
        for (i = 0; i < vec_len(vlib_mains); i++)
          vec_add1 (gm->my_vlib_mains, vlib_mains[i]);
      }

    while (1) {
        vlib_process_suspend (vm, 5.0);
        vector_rate = vlib_last_vector_length_per_node (vm);
        *gm->vector_rate_ptr = vector_rate;
        now = vlib_time_now(vm);
        dt = now - last_runtime;
        input_packets =  vnet_get_aggregate_rx_packets();
        *gm->input_rate_ptr = (f64)(input_packets - last_input_packets) / dt;
        last_runtime = now;
        last_input_packets = input_packets;

        new_sig_errors = get_significant_errors(gm);
        *gm->sig_error_rate_ptr = 
            ((f64)(new_sig_errors - gm->last_sig_errors)) / dt;
        gm->last_sig_errors = new_sig_errors;
    }

    return 0; /* not so much */
}

VLIB_REGISTER_NODE (gmon_process_node,static) = {
    .function = gmon_process,
    .type = VLIB_NODE_TYPE_PROCESS,
    .name = "gmon-process",
};

static clib_error_t *
gmon_init (vlib_main_t *vm)
{
    gmon_main_t *gm = &gmon_main;
    api_main_t * am = &api_main;
    pid_t *swp = 0;
    f64 *v = 0;
    clib_error_t * error;

    if ((error = vlib_call_init_function(vm, vpe_api_init)))
        return(error);

    /* Make sure that /global-vm is owned as directed */
    svm_region_init_chroot_uid_gid (am->root_path, am->api_uid, am->api_gid);

    gm->vlib_main = vm;
    gm->svmdb_client = svmdb_map_chroot(am->root_path);

    /* Find or create, set to zero */
    vec_add1 (v, 0.0);
    svmdb_local_set_vec_variable(gm->svmdb_client, 
                                 "vpp_vector_rate", 
                                 (char *)v, sizeof (*v));
    vec_free(v);
    vec_add1 (v, 0.0);
    svmdb_local_set_vec_variable(gm->svmdb_client, 
                                 "vpp_input_rate", 
                                 (char *)v, sizeof (*v));
    vec_free(v);
    vec_add1 (v, 0.0);
    svmdb_local_set_vec_variable(gm->svmdb_client, 
                                 "vpp_sig_error_rate", 
                                 (char *)v, sizeof (*v));
    vec_free(v);

    vec_add1 (swp, 0.0);
    svmdb_local_set_vec_variable(gm->svmdb_client, 
                                 "vpp_pid", 
                                 (char *)swp, sizeof (*swp));
    vec_free(swp);

    /* the value cells will never move, so acquire references to them */
    gm->vector_rate_ptr = 
        svmdb_local_get_variable_reference (gm->svmdb_client,
                                            SVMDB_NAMESPACE_VEC, 
                                            "vpp_vector_rate");
    gm->input_rate_ptr = 
        svmdb_local_get_variable_reference (gm->svmdb_client,
                                            SVMDB_NAMESPACE_VEC, 
                                            "vpp_input_rate");
    gm->sig_error_rate_ptr = 
        svmdb_local_get_variable_reference (gm->svmdb_client,
                                            SVMDB_NAMESPACE_VEC, 
                                            "vpp_sig_error_rate");
    gm->vpef_pid_ptr = 
        svmdb_local_get_variable_reference (gm->svmdb_client,
                                            SVMDB_NAMESPACE_VEC, 
                                            "vpp_pid");
    return 0;
}

VLIB_INIT_FUNCTION (gmon_init);

static clib_error_t *gmon_exit (vlib_main_t *vm)
{
    gmon_main_t *gm = &gmon_main;

    if (gm->vector_rate_ptr) {
        *gm->vector_rate_ptr = 0.0;
        *gm->vpef_pid_ptr = 0;
        *gm->input_rate_ptr = 0.0;
        *gm->sig_error_rate_ptr = 0.0;
        svm_region_unmap ((void *) gm->svmdb_client->db_rp);
        vec_free(gm->svmdb_client);
    }
    return 0;
}
VLIB_MAIN_LOOP_EXIT_FUNCTION (gmon_exit);

static int 
significant_error_enable_disable (gmon_main_t * gm, 
                                  u32 index, int enable)
{
  vlib_main_t * vm = gm->vlib_main;
  vlib_error_main_t * em = &vm->error_main;

  if (index >= vec_len (em->counters))
    return VNET_API_ERROR_NO_SUCH_ENTRY;

  gm->sig_error_bitmap = clib_bitmap_set (gm->sig_error_bitmap, index, enable);
  return 0;
}

static clib_error_t *
set_significant_error_command_fn (vlib_main_t * vm,
		 unformat_input_t * input,
		 vlib_cli_command_t * cmd)
{
  u32 index;
  int enable = 1;
  int rv;
  gmon_main_t *gm = &gmon_main;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
    if (unformat (input, "%d", &index))
      ;
    else if (unformat (input, "disable"))
      enable = 0;
    else
      return clib_error_return (0, "unknown input `%U'",
                                format_unformat_error, input);
  }

  rv = significant_error_enable_disable (gm, index, enable);

  switch (rv)
    {
    case 0:
      break;

    default:
      return clib_error_return 
        (0, "significant_error_enable_disable returned %d", rv);
    }

  return 0;
}

VLIB_CLI_COMMAND (set_significant_error_command, static) = {
    .path = "set significant error",
    .short_help = "set significant error <counter-index-nnn>",
    .function = set_significant_error_command_fn,
};
