/*
 * 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.
 */
/*------------------------------------------------------------------
 * format.c -- see notice below
 *
 * October 2003, Eliot Dresselhaus
 *
 * Modifications to this file Copyright (c) 2003 by cisco Systems, Inc.
 * All rights reserved.
 *------------------------------------------------------------------
 */

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

#include <stdarg.h>		/* va_start, etc */

#ifdef CLIB_UNIX
#include <unistd.h>
#include <stdio.h>
#endif

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

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

typedef struct
{
  /* Output number in this base. */
  u8 base;

  /* Number of show of 64 bit number. */
  u8 n_bits;

  /* Signed or unsigned. */
  u8 is_signed;

  /* Output digits uppercase (not lowercase) %X versus %x. */
  u8 uppercase_digits;
} format_integer_options_t;

static u8 *format_integer (u8 * s, u64 number,
			   format_integer_options_t * options);
static u8 *format_float (u8 * s, f64 x, uword n_digits_to_print,
			 uword output_style);

typedef struct
{
  /* String justification: + => right, - => left, = => center. */
  uword justify;

  /* Width of string (before and after decimal point for numbers).
     0 => natural width. */
  uword width[2];

  /* Long => 'l', long long 'L', int 0. */
  uword how_long;

  /* Pad character.  Defaults to space. */
  uword pad_char;
} format_info_t;

static u8 *
justify (u8 * s, format_info_t * fi, uword s_len_orig)
{
  uword i0, l0, l1;

  i0 = s_len_orig;
  l0 = i0 + fi->width[0];
  l1 = vec_len (s);

  /* If width is zero user returned width. */
  if (l0 == i0)
    l0 = l1;

  if (l1 > l0)
    _vec_len (s) = l0;
  else if (l0 > l1)
    {
      uword n = l0 - l1;
      uword n_left = 0, n_right = 0;

      switch (fi->justify)
	{
	case '-':
	  n_right = n;
	  break;

	case '+':
	  n_left = n;
	  break;

	case '=':
	  n_right = n_left = n / 2;
	  if (n % 2)
	    n_left++;
	  break;
	}
      if (n_left > 0)
	{
	  vec_insert (s, n_left, i0);
	  memset (s + i0, fi->pad_char, n_left);
	  l1 = vec_len (s);
	}
      if (n_right > 0)
	{
	  vec_resize (s, n_right);
	  memset (s + l1, fi->pad_char, n_right);
	}
    }
  return s;
}

static u8 *
do_percent (u8 ** _s, u8 * fmt, va_list * va)
{
  u8 *s = *_s;
  uword c;

  u8 *f = fmt;

  format_info_t fi = {
    .justify = '+',
    .width = {0},
    .pad_char = ' ',
    .how_long = 0,
  };

  uword i;

  ASSERT (f[0] == '%');

  switch (c = *++f)
    {
    case '%':
      /* %% => % */
      vec_add1 (s, c);
      f++;
      goto done;

    case '-':
    case '+':
    case '=':
      fi.justify = c;
      c = *++f;
      break;
    }

  /* Parse width0 . width1. */
  {
    uword is_first_digit = 1;

    fi.width[0] = fi.width[1] = 0;
    for (i = 0; i < 2; i++)
      {
	if (c == '0' && i == 0 && is_first_digit)
	  fi.pad_char = '0';
	is_first_digit = 0;
	if (c == '*')
	  {
	    fi.width[i] = va_arg (*va, int);
	    c = *++f;
	  }
	else
	  {
	    while (c >= '0' && c <= '9')
	      {
		fi.width[i] = 10 * fi.width[i] + (c - '0');
		c = *++f;
	      }
	  }
	if (c != '.')
	  break;
	c = *++f;
      }
  }

  /* Parse %l* and %L* */
  switch (c)
    {
    case 'w':
      /* word format. */
      fi.how_long = 'w';
      c = *++f;
      break;

    case 'L':
    case 'l':
      fi.how_long = c;
      c = *++f;
      if (c == 'l' && *f == 'l')
	{
	  fi.how_long = 'L';
	  c = *++f;
	}
      break;
    }

  /* Finally we are ready for format letter. */
  if (c != 0)
    {
      uword s_initial_len = vec_len (s);
      format_integer_options_t o = {
	.is_signed = 0,
	.base = 10,
	.n_bits = BITS (uword),
	.uppercase_digits = 0,
      };

      f++;

      switch (c)
	{
	default:
	  {
	    /* Try to give a helpful error message. */
	    vec_free (s);
	    s = format (s, "**** CLIB unknown format `%%%c' ****", c);
	    goto done;
	  }

	case 'c':
	  vec_add1 (s, va_arg (*va, int));
	  break;

	case 'p':
	  vec_add1 (s, '0');
	  vec_add1 (s, 'x');

	  o.is_signed = 0;
	  o.n_bits = BITS (uword *);
	  o.base = 16;
	  o.uppercase_digits = 0;

	  s = format_integer (s, pointer_to_uword (va_arg (*va, void *)), &o);
	  break;

	case 'x':
	case 'X':
	case 'u':
	case 'd':
	  {
	    u64 number;

	    o.base = 10;
	    if (c == 'x' || c == 'X')
	      o.base = 16;
	    o.is_signed = c == 'd';
	    o.uppercase_digits = c == 'X';

	    switch (fi.how_long)
	      {
	      case 'L':
		number = va_arg (*va, unsigned long long);
		o.n_bits = BITS (unsigned long long);
		break;

	      case 'l':
		number = va_arg (*va, long);
		o.n_bits = BITS (long);
		break;

	      case 'w':
		number = va_arg (*va, word);
		o.n_bits = BITS (uword);
		break;

	      default:
		number = va_arg (*va, int);
		o.n_bits = BITS (int);
		break;
	      }

	    s = format_integer (s, number, &o);
	  }
	  break;

	case 's':
	case 'S':
	  {
	    char *cstring = va_arg (*va, char *);
	    uword len;

	    if (!cstring)
	      {
		cstring = "(nil)";
		len = 5;
	      }
	    else if (fi.width[1] != 0)
	      len = clib_min (strlen (cstring), fi.width[1]);
	    else
	      len = strlen (cstring);

	    /* %S => format string as C identifier (replace _ with space). */
	    if (c == 'S')
	      {
		for (i = 0; i < len; i++)
		  vec_add1 (s, cstring[i] == '_' ? ' ' : cstring[i]);
	      }
	    else
	      vec_add (s, cstring, len);
	  }
	  break;

	case 'v':
	  {
	    u8 *v = va_arg (*va, u8 *);
	    uword len;

	    if (fi.width[1] != 0)
	      len = clib_min (vec_len (v), fi.width[1]);
	    else
	      len = vec_len (v);

	    vec_add (s, v, len);
	  }
	  break;

	case 'f':
	case 'g':
	case 'e':
	  /* Floating point. */
	  ASSERT (fi.how_long == 0 || fi.how_long == 'l');
	  s = format_float (s, va_arg (*va, double), fi.width[1], c);
	  break;

	case 'U':
	  /* User defined function. */
	  {
	    typedef u8 *(user_func_t) (u8 * s, va_list * args);
	    user_func_t *u = va_arg (*va, user_func_t *);

	    s = (*u) (s, va);
	  }
	  break;
	}

      s = justify (s, &fi, s_initial_len);
    }

done:
  *_s = s;
  return f;
}

u8 *
va_format (u8 * s, const char *fmt, va_list * va)
{
  u8 *f = (u8 *) fmt, *g;
  u8 c;

  g = f;
  while (1)
    {
      c = *f;

      if (!c)
	break;

      if (c == '%')
	{
	  if (f > g)
	    vec_add (s, g, f - g);
	  f = g = do_percent (&s, f, va);
	}
      else
	{
	  f++;
	}
    }

  if (f > g)
    vec_add (s, g, f - g);

  return s;
}

u8 *
format (u8 * s, const char *fmt, ...)
{
  va_list va;
  va_start (va, fmt);
  s = va_format (s, fmt, &va);
  va_end (va);
  return s;
}

word
va_fformat (FILE * f, char *fmt, va_list * va)
{
  word ret;
  u8 *s;

  s = va_format (0, fmt, va);

#ifdef CLIB_UNIX
  if (f)
    {
      ret = fwrite (s, vec_len (s), 1, f);
    }
  else
#endif /* CLIB_UNIX */
    {
      ret = 0;
      os_puts (s, vec_len (s), /* is_error */ 0);
    }

  vec_free (s);
  return ret;
}

word
fformat (FILE * f, char *fmt, ...)
{
  va_list va;
  word ret;

  va_start (va, fmt);
  ret = va_fformat (f, fmt, &va);
  va_end (va);

  return (ret);
}

#ifdef CLIB_UNIX
word
fdformat (int fd, char *fmt, ...)
{
  word ret;
  u8 *s;
  va_list va;

  va_start (va, fmt);
  s = va_format (0, fmt, &va);
  va_end (va);

  ret = write (fd, s, vec_len (s));
  vec_free (s);
  return ret;
}
#endif

/* Format integral type. */
static u8 *
format_integer (u8 * s, u64 number, format_integer_options_t * options)
{
  u64 q;
  u32 r;
  u8 digit_buffer[128];
  u8 *d = digit_buffer + sizeof (digit_buffer);
  word c, base;

  if (options->is_signed && (i64) number < 0)
    {
      number = -number;
      vec_add1 (s, '-');
    }

  if (options->n_bits < BITS (number))
    number &= ((u64) 1 << options->n_bits) - 1;

  base = options->base;

  while (1)
    {
      q = number / base;
      r = number % base;

      if (r < 10 + 26 + 26)
	{
	  if (r < 10)
	    c = '0' + r;
	  else if (r < 10 + 26)
	    c = 'a' + (r - 10);
	  else
	    c = 'A' + (r - 10 - 26);

	  if (options->uppercase_digits
	      && base <= 10 + 26 && c >= 'a' && c <= 'z')
	    c += 'A' - 'a';

	  *--d = c;
	}
      else			/* will never happen, warning be gone */
	{
	  *--d = '?';
	}

      if (q == 0)
	break;

      number = q;
    }

  vec_add (s, d, digit_buffer + sizeof (digit_buffer) - d);
  return s;
}

/* Floating point formatting. */
/* Deconstruct IEEE 64 bit number into sign exponent and fraction. */
#define f64_down(f,sign,expon,fraction)				\
do {								\
  union { u64 u; f64 f; } _f64_down_tmp;			\
  _f64_down_tmp.f = (f);					\
  (sign) = (_f64_down_tmp.u >> 63);				\
  (expon) = ((_f64_down_tmp.u >> 52) & 0x7ff) - 1023;		\
  (fraction) = ((_f64_down_tmp.u << 12) >> 12) | ((u64) 1 << 52); \
} while (0)

/* Construct IEEE 64 bit number. */
static f64
f64_up (uword sign, word expon, u64 fraction)
{
  union
  {
    u64 u;
    f64 f;
  } tmp;

  tmp.u = (u64) ((sign) != 0) << 63;

  expon += 1023;
  if (expon > 1023)
    expon = 1023;
  if (expon < 0)
    expon = 0;
  tmp.u |= (u64) expon << 52;

  tmp.u |= fraction & (((u64) 1 << 52) - 1);

  return tmp.f;
}

/* Returns approximate precision of number given its exponent. */
static f64
f64_precision (int base2_expon)
{
  static int n_bits = 0;

  if (!n_bits)
    {
      /* Compute number of significant bits in floating point representation. */
      f64 one = 0;
      f64 small = 1;

      while (one != 1)
	{
	  small *= .5;
	  n_bits++;
	  one = 1 + small;
	}
    }

  return f64_up (0, base2_expon - n_bits, 0);
}

/* Return x 10^n */
static f64
times_power_of_ten (f64 x, int n)
{
  if (n >= 0)
    {
      static f64 t[8] = { 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, };
      while (n >= 8)
	{
	  x *= 1e+8;
	  n -= 8;
	}
      return x * t[n];
    }
  else
    {
      static f64 t[8] = { 1e-0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, };
      while (n <= -8)
	{
	  x *= 1e-8;
	  n += 8;
	}
      return x * t[-n];
    }

}

/* Write x = y * 10^expon with 1 < y < 10. */
static f64
normalize (f64 x, word * expon_return, f64 * prec_return)
{
  word expon2, expon10;
  CLIB_UNUSED (u64 fraction);
  CLIB_UNUSED (word sign);
  f64 prec;

  f64_down (x, sign, expon2, fraction);

  expon10 =
    .5 +
    expon2 * .301029995663981195213738894724493 /* Log (2) / Log (10) */ ;

  prec = f64_precision (expon2);
  x = times_power_of_ten (x, -expon10);
  prec = times_power_of_ten (prec, -expon10);

  while (x < 1)
    {
      x *= 10;
      prec *= 10;
      expon10--;
    }

  while (x > 10)
    {
      x *= .1;
      prec *= .1;
      expon10++;
    }

  if (x + prec >= 10)
    {
      x = 1;
      expon10++;
    }

  *expon_return = expon10;
  *prec_return = prec;

  return x;
}

static u8 *
add_some_zeros (u8 * s, uword n_zeros)
{
  while (n_zeros > 0)
    {
      vec_add1 (s, '0');
      n_zeros--;
    }
  return s;
}

/* Format a floating point number with the given number of fractional
   digits (e.g. 1.2345 with 2 fraction digits yields "1.23") and output style. */
static u8 *
format_float (u8 * s, f64 x, uword n_fraction_digits, uword output_style)
{
  f64 prec;
  word sign, expon, n_fraction_done, added_decimal_point;
  /* Position of decimal point relative to where we are. */
  word decimal_point;

  /* Default number of digits to print when its not specified. */
  if (n_fraction_digits == ~0)
    n_fraction_digits = 7;
  n_fraction_done = 0;
  decimal_point = 0;
  added_decimal_point = 0;
  sign = expon = 0;

  /* Special case: zero. */
  if (x == 0)
    {
    do_zero:
      vec_add1 (s, '0');
      goto done;
    }

  if (x < 0)
    {
      x = -x;
      sign = 1;
    }

  /* Check for infinity. */
  if (x == x / 2)
    return format (s, "%cinfinity", sign ? '-' : '+');

  x = normalize (x, &expon, &prec);

  /* Not enough digits to print anything: so just print 0 */
  if ((word) - expon > (word) n_fraction_digits
      && (output_style == 'f' || (output_style == 'g')))
    goto do_zero;

  if (sign)
    vec_add1 (s, '-');

  if (output_style == 'f'
      || (output_style == 'g' && expon > -10 && expon < 10))
    {
      if (expon < 0)
	{
	  /* Add decimal point and leading zeros. */
	  vec_add1 (s, '.');
	  n_fraction_done = clib_min (-(expon + 1), n_fraction_digits);
	  s = add_some_zeros (s, n_fraction_done);
	  decimal_point = -n_fraction_done;
	  added_decimal_point = 1;
	}
      else
	decimal_point = expon + 1;
    }
  else
    {
      /* Exponential output style. */
      decimal_point = 1;
      output_style = 'e';
    }

  while (1)
    {
      uword digit;

      /* Number is smaller than precision: call it zero. */
      if (x < prec)
	break;

      digit = x;
      x -= digit;
      if (x + prec >= 1)
	{
	  digit++;
	  x -= 1;
	}

      /* Round last printed digit. */
      if (decimal_point <= 0
	  && n_fraction_done + 1 == n_fraction_digits && digit < 9)
	digit += x >= .5;

      vec_add1 (s, '0' + digit);

      /* Move rightwards towards/away from decimal point. */
      decimal_point--;

      n_fraction_done += decimal_point < 0;
      if (decimal_point <= 0 && n_fraction_done >= n_fraction_digits)
	break;

      if (decimal_point == 0 && x != 0)
	{
	  vec_add1 (s, '.');
	  added_decimal_point = 1;
	}

      x *= 10;
      prec *= 10;
    }

done:
  if (decimal_point > 0)
    {
      s = add_some_zeros (s, decimal_point);
      decimal_point = 0;
    }

  if (n_fraction_done < n_fraction_digits)
    {
      if (!added_decimal_point)
	vec_add1 (s, '.');
      s = add_some_zeros (s, n_fraction_digits - n_fraction_done);
    }

  if (output_style == 'e')
    s = format (s, "e%wd", expon);

  return s;
}


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