/*
 * Copyright (c) 2020 Intel 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.
 */
/*
 * node_init.c: node march variant startup initialization
 *
 * Copyright (c) 2020 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <sys/types.h>
#include <fcntl.h>
#include <vlib/vlib.h>

typedef struct _vlib_node_march_variant
{
  struct _vlib_node_march_variant *next_variant;
  char *name;
} vlib_node_march_variant_t;

#define VLIB_VARIANT_REGISTER()			\
  static vlib_node_march_variant_t			\
  CLIB_MARCH_VARIANT##variant;				\
							\
  static void __clib_constructor			\
  CLIB_MARCH_VARIANT##_register (void)			\
  {							\
    extern vlib_node_march_variant_t *variants;	\
    vlib_node_march_variant_t *v;			\
    v = & CLIB_MARCH_VARIANT##variant;			\
    v->name = CLIB_MARCH_VARIANT_STR;			\
    v->next_variant = variants;			\
    variants = v;					\
  }							\

VLIB_VARIANT_REGISTER ();

#ifndef CLIB_MARCH_VARIANT

vlib_node_march_variant_t *variants = 0;

uword
unformat_vlib_node_variant (unformat_input_t * input, va_list * args)
{
  u8 **variant = va_arg (*args, u8 **);
  vlib_node_march_variant_t *v = variants;

  if (!unformat (input, "%v", variant))
    return 0;

  while (v)
    {
      if (!strncmp (v->name, (char *) *variant, vec_len (*variant)))
	return 1;

      v = v->next_variant;
    }

  return 0;
}

static_always_inline void
vlib_update_nr_variant_default (vlib_node_registration_t *nr, u8 *variant)
{
  vlib_node_fn_registration_t *fnr = nr->node_fn_registrations;
  vlib_node_fn_registration_t *p_reg = 0;
  vlib_node_fn_registration_t *v_reg = 0;
  u32 tmp;

  while (fnr)
    {
      /* which is the highest priority registration */
      if (!p_reg || fnr->priority > p_reg->priority)
	p_reg = fnr;

      /* which is the variant we want to prioritize */
      if (!strncmp (fnr->name, (char *) variant, vec_len (variant) - 1))
	v_reg = fnr;

      fnr = fnr->next_registration;
    }

  /* node doesn't have the variants */
  if (!v_reg)
    return;

  ASSERT (p_reg != 0 && v_reg != 0);

  /* swap priorities */
  tmp = p_reg->priority;
  p_reg->priority = v_reg->priority;
  v_reg->priority = tmp;

}

static clib_error_t *
vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input)
{
  clib_error_t *error = 0;
  vlib_node_registration_t *nr, **all;
  unformat_input_t sub_input;
  uword *hash = 0, *p;
  u8 *variant = 0;
  u8 *s = 0;

  all = 0;
  hash = hash_create_string (0, sizeof (uword));

  nr = vm->node_main.node_registrations;
  while (nr)
    {
      hash_set_mem (hash, nr->name, vec_len (all));
      vec_add1 (all, nr);

      nr = nr->next_registration;
    }

  /* specify prioritization defaults for all graph nodes */
  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "default %U", unformat_vlib_cli_sub_input,
		    &sub_input))
	{
	  while (unformat_check_input (&sub_input) != UNFORMAT_END_OF_INPUT)
	    {
	      if (!unformat (&sub_input, "variant %U",
			     unformat_vlib_node_variant, &variant))
		return clib_error_return (0,
					  "please specify a valid node variant");
	      vec_add1 (variant, 0);

	      nr = vm->node_main.node_registrations;
	      while (nr)
		{
		  vlib_update_nr_variant_default (nr, variant);
		  nr = nr->next_registration;
		}

	      vec_free (variant);
	    }
	}
      else /* specify prioritization for an individual graph node */
      if (unformat (input, "%s", &s))
	{
	  if (!(p = hash_get_mem (hash, s)))
	    {
	      error = clib_error_return (0,
					 "node variants: unknown graph node '%s'",
					 s);
	      break;
	    }

	  nr = vec_elt (all, p[0]);

	  if (unformat (input, "%U", unformat_vlib_cli_sub_input, &sub_input))
	    {
	      while (unformat_check_input (&sub_input) !=
		     UNFORMAT_END_OF_INPUT)
		{
		  if (!unformat (&sub_input, "variant %U",
				 unformat_vlib_node_variant, &variant))
		    return clib_error_return (0,
					      "please specify a valid node variant");
		  vec_add1 (variant, 0);

		  vlib_update_nr_variant_default (nr, variant);

		  vec_free (variant);
		}
	    }
	}
      else
	{
	  break;
	}
    }

  hash_free (hash);
  vec_free (all);
  unformat_free (input);

  return error;
}

VLIB_EARLY_CONFIG_FUNCTION (vlib_early_node_config, "node");

#endif

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