/* JSON trees
   Copyright (C) 2017-2022 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "json.h"
#include "pretty-print.h"
#include "math.h"
#include "selftest.h"

using namespace json;

/* class json::value.  */

/* Dump this json::value tree to OUTF.
   No formatting is done.  There are no guarantees about the order
   in which the key/value pairs of json::objects are printed.  */

void
value::dump (FILE *outf) const
{
  pretty_printer pp;
  pp_buffer (&pp)->stream = outf;
  print (&pp);
  pp_flush (&pp);
}

/* class json::object, a subclass of json::value, representing
   an unordered collection of key/value pairs.  */

/* json:object's dtor.  */

object::~object ()
{
  for (map_t::iterator it = m_map.begin (); it != m_map.end (); ++it)
    {
      free (const_cast <char *>((*it).first));
      delete ((*it).second);
    }
}

/* Implementation of json::value::print for json::object.  */

void
object::print (pretty_printer *pp) const
{
  /* Note that the order is not guaranteed.  */
  pp_character (pp, '{');
  for (map_t::iterator it = m_map.begin (); it != m_map.end (); ++it)
    {
      if (it != m_map.begin ())
	pp_string (pp, ", ");
      const char *key = const_cast <char *>((*it).first);
      value *value = (*it).second;
      pp_doublequote (pp);
      pp_string (pp, key); // FIXME: escaping?
      pp_doublequote (pp);
      pp_string (pp, ": ");
      value->print (pp);
    }
  pp_character (pp, '}');
}

/* Set the json::value * for KEY, taking ownership of V
   (and taking a copy of KEY if necessary).  */

void
object::set (const char *key, value *v)
{
  gcc_assert (key);
  gcc_assert (v);

  value **ptr = m_map.get (key);
  if (ptr)
    {
      /* If the key is already present, delete the existing value
	 and overwrite it.  */
      delete *ptr;
      *ptr = v;
    }
  else
    /* If the key wasn't already present, take a copy of the key,
       and store the value.  */
    m_map.put (xstrdup (key), v);
}

/* Get the json::value * for KEY.

   The object retains ownership of the value.  */

value *
object::get (const char *key) const
{
  gcc_assert (key);

  value **ptr = const_cast <map_t &> (m_map).get (key);
  if (ptr)
    return *ptr;
  else
    return NULL;
}

/* class json::array, a subclass of json::value, representing
   an ordered collection of values.  */

/* json::array's dtor.  */

array::~array ()
{
  unsigned i;
  value *v;
  FOR_EACH_VEC_ELT (m_elements, i, v)
    delete v;
}

/* Implementation of json::value::print for json::array.  */

void
array::print (pretty_printer *pp) const
{
  pp_character (pp, '[');
  unsigned i;
  value *v;
  FOR_EACH_VEC_ELT (m_elements, i, v)
    {
      if (i)
	pp_string (pp, ", ");
      v->print (pp);
    }
  pp_character (pp, ']');
}

/* Append non-NULL value V to a json::array, taking ownership of V.  */

void
array::append (value *v)
{
  gcc_assert (v);
  m_elements.safe_push (v);
}

/* class json::float_number, a subclass of json::value, wrapping a double.  */

/* Implementation of json::value::print for json::float_number.  */

void
float_number::print (pretty_printer *pp) const
{
  char tmp[1024];
  snprintf (tmp, sizeof (tmp), "%g", m_value);
  pp_string (pp, tmp);
}

/* class json::integer_number, a subclass of json::value, wrapping a long.  */

/* Implementation of json::value::print for json::integer_number.  */

void
integer_number::print (pretty_printer *pp) const
{
  char tmp[1024];
  snprintf (tmp, sizeof (tmp), "%ld", m_value);
  pp_string (pp, tmp);
}


/* class json::string, a subclass of json::value.  */

/* json::string's ctor.  */

string::string (const char *utf8)
{
  gcc_assert (utf8);
  m_utf8 = xstrdup (utf8);
}

/* Implementation of json::value::print for json::string.  */

void
string::print (pretty_printer *pp) const
{
  pp_character (pp, '"');
  for (const char *ptr = m_utf8; *ptr; ptr++)
    {
      char ch = *ptr;
      switch (ch)
	{
	case '"':
	  pp_string (pp, "\\\"");
	  break;
	case '\\':
	  pp_string (pp, "\\n");
	  break;
	case '\b':
	  pp_string (pp, "\\b");
	  break;
	case '\f':
	  pp_string (pp, "\\f");
	  break;
	case '\n':
	  pp_string (pp, "\\n");
	  break;
	case '\r':
	  pp_string (pp, "\\r");
	  break;
	case '\t':
	  pp_string (pp, "\\t");
	  break;

	default:
	  pp_character (pp, ch);
	}
    }
  pp_character (pp, '"');
}

/* class json::literal, a subclass of json::value.  */

/* Implementation of json::value::print for json::literal.  */

void
literal::print (pretty_printer *pp) const
{
  switch (m_kind)
    {
    case JSON_TRUE:
      pp_string (pp, "true");
      break;
    case JSON_FALSE:
      pp_string (pp, "false");
      break;
    case JSON_NULL:
      pp_string (pp, "null");
      break;
    default:
      gcc_unreachable ();
    }
}


#if CHECKING_P

namespace selftest {

/* Selftests.  */

/* Verify that JV->print () prints EXPECTED_JSON.  */

static void
assert_print_eq (const json::value &jv, const char *expected_json)
{
  pretty_printer pp;
  jv.print (&pp);
  ASSERT_STREQ (expected_json, pp_formatted_text (&pp));
}

/* Verify that object::get works as expected.  */

static void
test_object_get ()
{
  object obj;
  value *val = new json::string ("value");
  obj.set ("foo", val);
  ASSERT_EQ (obj.get ("foo"), val);
  ASSERT_EQ (obj.get ("not-present"), NULL);
}

/* Verify that JSON objects are written correctly.  We can't test more than
   one key/value pair, as we don't impose a guaranteed ordering.  */

static void
test_writing_objects ()
{
  object obj;
  obj.set ("foo", new json::string ("bar"));
  assert_print_eq (obj, "{\"foo\": \"bar\"}");
}

/* Verify that JSON arrays are written correctly.  */

static void
test_writing_arrays ()
{
  array arr;
  assert_print_eq (arr, "[]");

  arr.append (new json::string ("foo"));
  assert_print_eq (arr, "[\"foo\"]");

  arr.append (new json::string ("bar"));
  assert_print_eq (arr, "[\"foo\", \"bar\"]");
}

/* Verify that JSON numbers are written correctly.  */

static void
test_writing_float_numbers ()
{
  assert_print_eq (float_number (0), "0");
  assert_print_eq (float_number (42), "42");
  assert_print_eq (float_number (-100), "-100");
  assert_print_eq (float_number (123456789), "1.23457e+08");
}

static void
test_writing_integer_numbers ()
{
  assert_print_eq (integer_number (0), "0");
  assert_print_eq (integer_number (42), "42");
  assert_print_eq (integer_number (-100), "-100");
  assert_print_eq (integer_number (123456789), "123456789");
  assert_print_eq (integer_number (-123456789), "-123456789");
}

/* Verify that JSON strings are written correctly.  */

static void
test_writing_strings ()
{
  string foo ("foo");
  assert_print_eq (foo, "\"foo\"");

  string contains_quotes ("before \"quoted\" after");
  assert_print_eq (contains_quotes, "\"before \\\"quoted\\\" after\"");
}

/* Verify that JSON literals are written correctly.  */

static void
test_writing_literals ()
{
  assert_print_eq (literal (JSON_TRUE), "true");
  assert_print_eq (literal (JSON_FALSE), "false");
  assert_print_eq (literal (JSON_NULL), "null");

  assert_print_eq (literal (true), "true");
  assert_print_eq (literal (false), "false");
}

/* Run all of the selftests within this file.  */

void
json_cc_tests ()
{
  test_object_get ();
  test_writing_objects ();
  test_writing_arrays ();
  test_writing_float_numbers ();
  test_writing_integer_numbers ();
  test_writing_strings ();
  test_writing_literals ();
}

} // namespace selftest

#endif /* #if CHECKING_P */
