/*
 * 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
 */
static vlib_punt_reason_t punt_reason_last;

/**
 * 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;
} 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;

      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)
	{
	  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_alloc (vlib_punt_hdl_t client,
			const char *reason_name, 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;
  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);
}

/* 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:
 */
