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

*/
#include <inttypes.h>
#include <vat/json_format.h>
#include <vnet/ip/ip.h>
#include <vppinfra/vec.h>

#define VAT_TAB_WIDTH               2

typedef struct vat_print_ctx_s {
    FILE *ofp;
    u32 indent;
} vat_print_ctx_t;

/* Format an IP4 address. */
static u8 * vat_json_format_ip4_address (u8 * s, va_list * args)
{
  u8 * a = va_arg (*args, u8 *);
  return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
}

/* Format an IP6 address. */
static u8 * vat_json_format_ip6_address (u8 * s, va_list * args)
{
  ip6_address_t * a = va_arg (*args, ip6_address_t *);
  u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;

  i_max_n_zero = ARRAY_LEN (a->as_u16);
  max_n_zeros = 0;
  i_first_zero = i_max_n_zero;
  n_zeros = 0;
  for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
    {
      u32 is_zero = a->as_u16[i] == 0;
      if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
        {
          i_first_zero = i;
          n_zeros = 0;
        }
      n_zeros += is_zero;
      if ((! is_zero && n_zeros > max_n_zeros)
          || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
        {
          i_max_n_zero = i_first_zero;
          max_n_zeros = n_zeros;
          i_first_zero = ARRAY_LEN (a->as_u16);
          n_zeros = 0;
        }
    }

  last_double_colon = 0;
  for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
    {
      if (i == i_max_n_zero && max_n_zeros > 1)
        {
          s = format (s, "::");
          i += max_n_zeros - 1;
          last_double_colon = 1;
        }
      else
        {
          s = format (s, "%s%x",
                      (last_double_colon || i == 0) ? "" : ":",
                      clib_net_to_host_u16 (a->as_u16[i]));
          last_double_colon = 0;
        }
    }

  return s;
}

static void
vat_json_indent_print (vat_print_ctx_t *ctx)
{
    int i;
    for (i=0; i<ctx->indent * VAT_TAB_WIDTH; i++) {
        fformat(ctx->ofp, " ");
    }
}

static void
vat_json_indent_line (vat_print_ctx_t * ctx, char * fmt, ...)
{
    va_list va;

    vat_json_indent_print(ctx);
    va_start(va, fmt);
    va_fformat(ctx->ofp, fmt, &va);
    va_end(va);
}

static u8
is_num_only (vat_json_node_t * p)
{
    vat_json_node_t * elem;
    vec_foreach(elem, p) {
        if (VAT_JSON_INT != elem->type &&
                VAT_JSON_UINT != elem->type) {
            return 0;
        }
    }
    return 1;
}

static void
vat_json_print_internal (vat_print_ctx_t *ctx, vat_json_node_t *node)
{
#define P(fmt,...) fformat(ctx->ofp, fmt, ##__VA_ARGS__)
#define PL(fmt,...) fformat(ctx->ofp, fmt"\n", ##__VA_ARGS__)
#define PPL(fmt,...) vat_json_indent_line(ctx, fmt"\n", ##__VA_ARGS__)
#define PP(fmt,...) vat_json_indent_line(ctx, fmt, ##__VA_ARGS__)
#define INCR (ctx->indent++)
#define DECR (ctx->indent--)

    vat_json_pair_t *pair;
    u32 i, count;
    vat_json_node_t *elem;
    u8 num_only = 0;

    if (!node) {
        return;
    }

    switch (node->type) {
    case VAT_JSON_OBJECT:
        count = vec_len(node->pairs);
        if (count >= 1) {
            PL("{");
            INCR;
            for (i=0; i<count; i++) {
                pair = &node->pairs[i];
                PP("\"%s\": ", pair->name);
                vat_json_print_internal(ctx, &pair->value);
                if (i < count - 1) {
                    P(",");
                }
                PL();
            }
            DECR;
            PP("}");
        } else { P("{}"); }
        break;
    case VAT_JSON_ARRAY:
        num_only = is_num_only(node->array);
        count = vec_len(node->array);
        if (count >= 1) {
            if (num_only)
                P("[");
            else
                PL("[ ");
            INCR;
            for (i=0; i<count; i++) {
                elem = &node->array[i];
                if (!num_only) {
                    vat_json_indent_print(ctx);
                }
                vat_json_print_internal(ctx, elem);
                if (i < count - 1) {
                    if (num_only) {
                        P(", ");
                    } else {
                        P(",");
                    }
                }
                if (!num_only) PL();
            }
            DECR;
            if (!num_only)
                PP("]");
            else
                P("]");
        } else { P("[]"); }
        break;
    case VAT_JSON_INT:
        P("%d", node->sint);
        break;
    case VAT_JSON_UINT:
        P("%"PRIu64, node->uint);
        break;
    case VAT_JSON_REAL:
        P("%f", node->real);
        break;
    case VAT_JSON_STRING:
        P("\"%s\"", node->string);
        break;
    case VAT_JSON_IPV4:
        P("\"%U\"", vat_json_format_ip4_address, &node->ip4);
        break;
    case VAT_JSON_IPV6:
        P("\"%U\"", vat_json_format_ip6_address, &node->ip6);
        break;
    default:
        break;
    }
#undef PPL
#undef PP
#undef PL
#undef P
}

void vat_json_print(FILE *ofp, vat_json_node_t *node)
{
    vat_print_ctx_t ctx;
    memset(&ctx, 0, sizeof ctx);
    ctx.indent = 0;
    ctx.ofp = ofp;
    fformat(ofp, "\n");
    vat_json_print_internal(&ctx, node);
    fformat(ofp, "\n");
}

void vat_json_free (vat_json_node_t *node)
{
    int i = 0;

    if (NULL == node) {
        return;
    }
    switch (node->type) {
    case VAT_JSON_OBJECT:
        for (i = 0; i < vec_len(node->pairs); i++) {
            vat_json_free(&node->pairs[i].value);
        }
        if (NULL != node->pairs) {
            vec_free(node->pairs);
        }
        break;
    case VAT_JSON_ARRAY:
        for (i = 0; i < vec_len(node->array); i++) {
            vat_json_free(&node->array[i]);
        }
        if (NULL != node->array) {
            vec_free(node->array);
        }
        break;
    case VAT_JSON_STRING:
        if (NULL != node->string) {
            vec_free(node->string);
        }
        break;
    default:
        break;
    }
}
