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