/*
 * Copyright (c) 2015 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.
 */
/*
  Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus

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

/* Error reporting. */
#include <stdarg.h>

#include <vppinfra/clib.h>	/* for HAVE_ERRNO */

#ifdef CLIB_LINUX_KERNEL
#include <linux/unistd.h>	/* for write */
#include <linux/kernel.h>	/* for printk */
#endif

#ifdef CLIB_UNIX
#include <unistd.h>		/* for write */
#include <stdio.h>		/* for printf */
#define HAVE_ERRNO
#endif

#ifdef CLIB_STANDALONE
#include <vppinfra/standalone_stdio.h>	/* for printf */
#endif

#include <vppinfra/string.h>
#include <vppinfra/mem.h>
#include <vppinfra/vec.h>
#include <vppinfra/format.h>
#include <vppinfra/error.h>
#include <vppinfra/hash.h>
#include <vppinfra/os.h>	/* for os_panic/os_exit/os_puts */

typedef struct
{
  clib_error_handler_func_t *func;
  void *arg;
} clib_error_handler_t;

static clib_error_handler_t *handlers = 0;

__clib_export void
clib_error_register_handler (clib_error_handler_func_t func, void *arg)
{
  clib_error_handler_t h = {.func = func,.arg = arg, };
  vec_add1 (handlers, h);
}

static void
debugger (void)
{
  os_panic ();
}

static void
error_exit (int code)
{
  os_exit (code);
}

static u8 *
dispatch_message (u8 * msg)
{
  word i;

  if (!msg)
    return msg;

  for (i = 0; i < vec_len (handlers); i++)
    handlers[i].func (handlers[i].arg, msg, vec_len (msg));

  /* If no message handler is specified provide a default one. */
  if (vec_len (handlers) == 0)
    os_puts (msg, vec_len (msg), /* is_error */ 1);

  return msg;
}

__clib_export void
_clib_error (int how_to_die, const char *function_name, uword line_number,
	     const char *fmt, ...)
{
  u8 *msg = 0;
  va_list va;

  if (function_name)
    {
      msg = format (msg, "%s:", function_name);
      if (line_number > 0)
	msg = format (msg, "%wd:", line_number);
      msg = format (msg, " ");
    }

  va_start (va, fmt);
  msg = va_format (msg, fmt, &va);
  va_end (va);

#ifdef HAVE_ERRNO
  if (how_to_die & CLIB_ERROR_ERRNO_VALID)
    msg = format (msg, ": %s (errno %d)", strerror (errno), errno);
#endif

  if (vec_end (msg)[-1] != '\n')
    vec_add1 (msg, '\n');

  msg = dispatch_message (msg);

  vec_free (msg);

  if (how_to_die & CLIB_ERROR_ABORT)
    debugger ();
  if (how_to_die & CLIB_ERROR_FATAL)
    error_exit (1);
}

__clib_export clib_error_t *
_clib_error_return (clib_error_t *errors, any code, uword flags,
		    const char *where, const char *fmt, ...)
{
  clib_error_t *e;
  va_list va;

#ifdef HAVE_ERRNO
  /* Save errno since it may be re-set before we'll need it. */
  word errno_save = errno;
#endif

  va_start (va, fmt);
  vec_add2 (errors, e, 1);
  if (fmt)
    e->what = va_format (0, fmt, &va);

#ifdef HAVE_ERRNO
  if (flags & CLIB_ERROR_ERRNO_VALID)
    {
      if (e->what)
	e->what = format (e->what, ": ");
      e->what = format (e->what, "%s", strerror (errno_save));
    }
#endif

  e->where = (u8 *) where;
  e->code = code;
  e->flags = flags;
  va_end (va);
  return errors;
}

__clib_export void *
clib_error_free_vector (clib_error_t * errors)
{
  clib_error_t *e;
  vec_foreach (e, errors) vec_free (e->what);
  vec_free (errors);
  return 0;
}

__clib_export u8 *
format_clib_error (u8 * s, va_list * va)
{
  clib_error_t *errors = va_arg (*va, clib_error_t *);
  clib_error_t *e;

  vec_foreach (e, errors)
  {
    if (!e->what)
      continue;

    if (e->where)
      {
	u8 *where = 0;

	if (e > errors)
	  where = format (where, "from ");
	where = format (where, "%s", e->where);

	s = format (s, "%v: ", where);
	vec_free (where);
      }

    s = format (s, "%v", e->what);
    if ((vec_end (errors) - 1) != e)
      s = format (s, "\n");
  }

  return s;
}

__clib_export clib_error_t *
_clib_error_report (clib_error_t * errors)
{
  if (errors)
    {
      u8 *msg = format (0, "%U", format_clib_error, errors);

      msg = dispatch_message (msg);
      vec_free (msg);

      if (errors->flags & CLIB_ERROR_ABORT)
	debugger ();
      if (errors->flags & CLIB_ERROR_FATAL)
	error_exit (1);

      clib_error_free (errors);
    }
  return 0;
}

#ifdef TEST

static error_t *
foo1 (int x)
{
  return error_return (0, "x is odd %d", x);
}

static error_t *
foo2 (int x)
{
  return error_return (0, "x is even %d", x);
}

static error_t *
foo (int x)
{
  error_t *e;
  if (x & 1)
    e = foo1 (x);
  else
    e = foo2 (x);
  if (e)
    return error_return (e, 0);
}

static void
error_handler (void *arg, char *msg, int msg_len)
{
  write (2, msg, msg_len);
}

int
main (int argc, char *argv[])
{
  error_t *e;

  register_error_handler (error_handler, 0);

  e = foo (getpid ());
  if (e)
    error_report (e);
  return 0;
}

#endif

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