/*
 * Copyright (c) 2019 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 <vlib/punt.h>

/**
 * The last allocated punt reason
 * Value 0 is reserved for invalid index.
 */
static vlib_punt_reason_t punt_reason_last = 1;

/**
 * Counters per punt-reason
 */
vlib_combined_counter_main_t punt_counters = {
  .name = "punt",
  .stat_segment_name = "/net/punt",
};

/**
 * A punt reason
 */
typedef struct punt_reason_data_t_
{
  /**
   * The reason name
   */
  u8 *pd_name;

  /**
   * The allocated reason value
   */
  vlib_punt_reason_t pd_reason;

  /**
   * Clients/owners that have registered this reason
   */
  u32 *pd_owners;

  /**
   * clients interested/listening to this reason
   */
  u32 pd_users;

  /**
   * function to invoke if a client becomes interested in the code.
   */
  punt_interested_listener_t pd_fn;

  /**
   * Data to pass to the callback
   */
  void *pd_data;
} punt_reason_data_t;

/**
 * data for each punt reason
 */
static punt_reason_data_t *punt_reason_data;

typedef enum punt_format_flags_t_
{
  PUNT_FORMAT_FLAG_NONE = 0,
  PUNT_FORMAT_FLAG_DETAIL = (1 << 0),
} punt_format_flags_t;

/**
 * A registration, by a client, to direct punted traffic to a given node
 */
typedef struct punt_reg_t_
{
  /**
   * Reason the packets were punted
   */
  vlib_punt_reason_t pr_reason;

  /**
   * number of clients that have made this registration
   */
  u16 pr_locks;

  /**
   * The edge from the punt dispatch node to the requested node
   */
  u16 pr_edge;

  /**
   * node-index to send punted packets to
   */
  u32 pr_node_index;
} punt_reg_t;

/**
 * Pool of registrations
 */
static punt_reg_t *punt_reg_pool;

/**
 * A DB of all the register nodes against punt reason and node index
 */
static uword *punt_reg_db;

/**
 * A DB used in the DP per-reason to dispatch packets to the requested nodes.
 * this is a vector of edges per-reason
 */
u16 **punt_dp_db;

/**
 * A client using the punt serivce and its registrations
 */
typedef struct punt_client_t_
{
  /**
   * The name of the client
   */
  u8 *pc_name;

  /**
   * The registrations is has made
   */
  u32 *pc_regs;
} punt_client_t;

/**
 * Pool of clients
 */
static punt_client_t *punt_client_pool;

/**
 * DB of clients key'd by their name
 */
static uword *punt_client_db;

u8 *
format_vlib_punt_reason (u8 * s, va_list * args)
{
  vlib_punt_reason_t pr = va_arg (*args, int);

  return (format (s, "[%d] %v", pr, punt_reason_data[pr].pd_name));
}

vlib_punt_hdl_t
vlib_punt_client_register (const char *who)
{
  u8 *pc_name;
  uword *p;
  u32 pci;

  pc_name = format (NULL, "%s", who);
  p = hash_get_mem (punt_client_db, pc_name);

  if (NULL == p)
    {
      punt_client_t *pc;

      pool_get (punt_client_pool, pc);
      pci = pc - punt_client_pool;

      pc->pc_name = pc_name;

      hash_set_mem (punt_client_db, pc->pc_name, pci);
    }
  else
    {
      pci = p[0];
      vec_free (pc_name);
    }

  return (pci);
}

static int
punt_validate_client (vlib_punt_hdl_t client)
{
  return (!pool_is_free_index (punt_client_pool, client));
}

static u64
punt_reg_mk_key (vlib_punt_reason_t reason, u32 node_index)
{
  return (((u64) node_index) << 32 | reason);
}

static u32
punt_reg_find (vlib_punt_reason_t reason, u32 node_index)
{
  uword *p;

  p = hash_get (punt_reg_db, punt_reg_mk_key (reason, node_index));

  if (p)
    return p[0];

  return ~0;
}

static void
punt_reg_add (const punt_reg_t * pr)
{
  hash_set (punt_reg_db, punt_reg_mk_key (pr->pr_reason,
					  pr->pr_node_index),
	    pr - punt_reg_pool);
}

static void
punt_reg_remove (const punt_reg_t * pr)
{
  hash_unset (punt_reg_db, punt_reg_mk_key (pr->pr_reason,
					    pr->pr_node_index));
}

/**
 * reconstruct the DP per-reason DB
 */
static void
punt_reg_mk_dp (vlib_punt_reason_t reason)
{
  u32 pri, *prip, *pris;
  const punt_reg_t *pr;
  u16 *edges, *old;
  u64 key;

  pris = NULL;
  edges = NULL;
  vec_validate (punt_dp_db, reason);

  old = punt_dp_db[reason];

  /* *INDENT-OFF* */
  hash_foreach (key, pri, punt_reg_db,
    ({
      vec_add1(pris, pri);
    }));
  /* *INDENT-ON* */

  /*
   * A check for an empty vector is done in the DP, so the a zero
   * length vector here is ok
   */
  vec_foreach (prip, pris)
  {
    pr = pool_elt_at_index (punt_reg_pool, *prip);

    if (pr->pr_reason == reason)
      vec_add1 (edges, pr->pr_edge);
  }

  /* atomic update of the DP */
  punt_dp_db[reason] = edges;

  vec_free (old);
}

int
vlib_punt_register (vlib_punt_hdl_t client,
		    vlib_punt_reason_t reason, const char *node_name)
{
  vlib_node_t *punt_to, *punt_from;
  punt_client_t *pc;
  vlib_main_t *vm;
  punt_reg_t *pr;
  u32 pri;

  if (reason >= punt_reason_last)
    return -1;
  if (!punt_validate_client (client))
    return -2;

  vm = vlib_get_main ();
  pc = pool_elt_at_index (punt_client_pool, client);
  punt_to = vlib_get_node_by_name (vm, (u8 *) node_name);
  punt_from = vlib_get_node_by_name (vm, (u8 *) "punt-dispatch");

  /*
   * find a global matching registration
   */
  pri = punt_reg_find (reason, punt_to->index);

  if (~0 != pri)
    {
      u32 pos;

      pos = vec_search (pc->pc_regs, pri);

      if (~0 != pos)
	{
	  /* duplicate registration for this client */
	  return -1;
	}

      pr = pool_elt_at_index (punt_reg_pool, pri);
    }
  else
    {
      pool_get (punt_reg_pool, pr);

      pr->pr_reason = reason;
      pr->pr_node_index = punt_to->index;
      pr->pr_edge = vlib_node_add_next (vm,
					punt_from->index, pr->pr_node_index);

      pri = pr - punt_reg_pool;

      if (0 == punt_reason_data[reason].pd_users++ &&
	  NULL != punt_reason_data[reason].pd_fn)
	punt_reason_data[reason].pd_fn (VLIB_ENABLE,
					punt_reason_data[reason].pd_data);

      punt_reg_add (pr);
    }

  /*
   * add this reg to the list the client has made
   */
  pr->pr_locks++;
  vec_add1 (pc->pc_regs, pri);

  punt_reg_mk_dp (reason);

  return 0;
}

int
vlib_punt_unregister (vlib_punt_hdl_t client,
		      vlib_punt_reason_t reason, const char *node_name)
{
  vlib_node_t *punt_to;
  punt_client_t *pc;
  vlib_main_t *vm;
  punt_reg_t *pr;
  u32 pri;

  if (reason >= punt_reason_last)
    return -1;

  vm = vlib_get_main ();
  pc = pool_elt_at_index (punt_client_pool, client);
  punt_to = vlib_get_node_by_name (vm, (u8 *) node_name);

  /*
   * construct a registration and check if it's one this client already has
   */
  pri = punt_reg_find (reason, punt_to->index);

  if (~0 != pri)
    {
      u32 pos;

      pos = vec_search (pc->pc_regs, pri);

      if (~0 == pos)
	{
	  /* not a registration for this client */
	  return -1;
	}
      vec_del1 (pc->pc_regs, pos);

      pr = pool_elt_at_index (punt_reg_pool, pri);

      pr->pr_locks--;

      if (0 == pr->pr_locks)
	{
	  if (0 == --punt_reason_data[reason].pd_users &&
	      NULL != punt_reason_data[reason].pd_fn)
	    punt_reason_data[reason].pd_fn (VLIB_DISABLE,
					    punt_reason_data[reason].pd_data);
	  punt_reg_remove (pr);
	  pool_put (punt_reg_pool, pr);
	}
    }

  /*
   * rebuild the DP data-base
   */
  punt_reg_mk_dp (reason);

  return (0);
}

int
vlib_punt_reason_validate (vlib_punt_reason_t reason)
{
  if (reason < punt_reason_last)
    return (0);

  return (-1);
}

int
vlib_punt_reason_alloc (vlib_punt_hdl_t client,
			const char *reason_name,
			punt_interested_listener_t fn,
			void *data, vlib_punt_reason_t * reason)
{
  vlib_punt_reason_t new;

  if (!punt_validate_client (client))
    return -2;

  new = punt_reason_last++;
  vec_validate (punt_reason_data, new);
  punt_reason_data[new].pd_name = format (NULL, "%s", reason_name);
  punt_reason_data[new].pd_reason = new;
  punt_reason_data[new].pd_fn = fn;
  punt_reason_data[new].pd_data = data;
  vec_add1 (punt_reason_data[new].pd_owners, client);

  vlib_validate_combined_counter (&punt_counters, new);
  vlib_zero_combined_counter (&punt_counters, new);

  *reason = new;

  /* build the DP data-base */
  punt_reg_mk_dp (*reason);

  return (0);
}

void
punt_reason_walk (punt_reason_walk_cb_t cb, void *ctx)
{
  punt_reason_data_t *pd;

  for (pd = punt_reason_data + 1; pd < vec_end (punt_reason_data); pd++)
    {
      cb (pd->pd_reason, pd->pd_name, ctx);
    }
}

/* Parse node name -> node index. */
uword
unformat_punt_client (unformat_input_t * input, va_list * args)
{
  u32 *result = va_arg (*args, u32 *);

  return unformat_user (input, unformat_hash_vec_string,
			punt_client_db, result);
}

u8 *
format_punt_reg (u8 * s, va_list * args)
{
  u32 pri = va_arg (*args, u32);
  punt_reg_t *pr;

  pr = pool_elt_at_index (punt_reg_pool, pri);

  s = format (s, "%U -> %U",
	      format_vlib_punt_reason, pr->pr_reason,
	      format_vlib_node_name, vlib_get_main (), pr->pr_node_index);

  return (s);
}

u8 *
format_punt_reason_data (u8 * s, va_list * args)
{
  punt_reason_data_t *pd = va_arg (*args, punt_reason_data_t *);
  punt_client_t *pc;
  u32 *pci;

  s = format (s, "[%d] %v from:[", pd->pd_reason, pd->pd_name);
  vec_foreach (pci, pd->pd_owners)
  {
    pc = pool_elt_at_index (punt_client_pool, *pci);
    s = format (s, "%v ", pc->pc_name);
  }
  s = format (s, "]");

  return (s);
}

u8 *
format_punt_client (u8 * s, va_list * args)
{
  u32 pci = va_arg (*args, u32);
  punt_format_flags_t flags = va_arg (*args, punt_format_flags_t);
  punt_client_t *pc;

  pc = pool_elt_at_index (punt_client_pool, pci);

  s = format (s, "%v", pc->pc_name);

  if (flags & PUNT_FORMAT_FLAG_DETAIL)
    {
      punt_reason_data_t *pd;
      u32 *pri;

      s = format (s, "\n registrations:");
      vec_foreach (pri, pc->pc_regs)
      {
	s = format (s, "\n  [%U]", format_punt_reg, *pri);
      }

      s = format (s, "\n reasons:");

      vec_foreach (pd, punt_reason_data)
      {
	u32 *tmp;

	vec_foreach (tmp, pd->pd_owners)
	{
	  if (*tmp == pci)
	    s = format (s, "\n  %U", format_punt_reason_data, pd);
	}
      }
    }
  return (s);
}

static clib_error_t *
punt_client_show (vlib_main_t * vm,
		  unformat_input_t * input, vlib_cli_command_t * cmd)
{
  u32 pci = ~0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%U", unformat_punt_client, &pci))
	;
      else
	break;
    }

  if (~0 != pci)
    {
      vlib_cli_output (vm, "%U", format_punt_client, pci,
		       PUNT_FORMAT_FLAG_DETAIL);
    }
  else
    {
      u8 *name;

      /* *INDENT-OFF* */
      hash_foreach(name, pci, punt_client_db,
        ({
          vlib_cli_output (vm, "%U", format_punt_client, pci,
                           PUNT_FORMAT_FLAG_NONE);
        }));
      /* *INDENT-ON* */
    }

  return (NULL);
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (punt_client_show_command, static) =
{
  .path = "show punt client",
  .short_help = "show client[s] registered with the punt infra",
  .function = punt_client_show,
};
/* *INDENT-ON* */

static clib_error_t *
punt_reason_show (vlib_main_t * vm,
		  unformat_input_t * input, vlib_cli_command_t * cmd)
{
  const punt_reason_data_t *pd;

  vec_foreach (pd, punt_reason_data)
  {
    vlib_cli_output (vm, "%U", format_punt_reason_data, pd);
  }

  return (NULL);
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (punt_reason_show_command, static) =
{
  .path = "show punt reasons",
  .short_help = "show all punt reasons",
  .function = punt_reason_show,
};
/* *INDENT-ON* */

static clib_error_t *
punt_db_show (vlib_main_t * vm,
	      unformat_input_t * input, vlib_cli_command_t * cmd)
{
  u32 pri, ii, jj;
  u64 key;

  /* *INDENT-OFF* */
  hash_foreach (key, pri, punt_reg_db,
    ({
      vlib_cli_output (vm, " %U", format_punt_reg, pri);
    }));
  /* *INDENT-ON* */

  vlib_cli_output (vm, "\nDerived data-plane data-base:");
  vlib_cli_output (vm,
		   "  (for each punt-reason the edge[s] from punt-dispatch)");

  vec_foreach_index (ii, punt_dp_db)
  {
    u8 *s = NULL;
    vlib_cli_output (vm, " %U", format_vlib_punt_reason, ii);

    vec_foreach_index (jj, punt_dp_db[ii])
    {
      s = format (s, "%d ", punt_dp_db[ii][jj]);
    }
    vlib_cli_output (vm, "   [%v]", s);
    vec_free (s);
  }

  return (NULL);
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (punt_db_show_command, static) =
{
  .path = "show punt db",
  .short_help = "show the punt DB",
  .function = punt_db_show,
};
/* *INDENT-ON* */

static clib_error_t *
punt_stats_show (vlib_main_t * vm,
		 unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vlib_combined_counter_main_t *cm = &punt_counters;
  vlib_counter_t c;
  u32 ii;

  for (ii = 0; ii < vlib_combined_counter_n_counters (cm); ii++)
    {
      vlib_get_combined_counter (cm, ii, &c);
      vlib_cli_output (vm, "%U packets:%lld bytes:%lld",
		       format_vlib_punt_reason, ii, c.packets, c.bytes);
    }

  return (NULL);
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (punt_stats_show_command, static) =
{
  .path = "show punt stats",
  .short_help = "show the punt stats",
  .function = punt_stats_show,
};
/* *INDENT-ON* */

static clib_error_t *
punt_init (vlib_main_t * vm)
{
  punt_client_db = hash_create_vec (0, sizeof (u8), sizeof (u32));

  return (NULL);
}

VLIB_INIT_FUNCTION (punt_init);

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