// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/assert.h"
#include "platform/json.h"
#include "vm/json_stream.h"
#include "vm/unit_test.h"

namespace dart {


TEST_CASE(JSON_ScanJSON) {
  const char* msg = "{ \"id\": 5, \"command\" : \"Debugger.pause\" }";

  JSONScanner scanner(msg);
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenIllegal);
  scanner.Scan();
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenLBrace);
  scanner.Scan();
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenString);
  EXPECT(scanner.IsStringLiteral("id"));
  scanner.Scan();
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenColon);
  scanner.Scan();
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenInteger);
  scanner.Scan();
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenComma);
  scanner.Scan();
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenString);
  EXPECT(scanner.IsStringLiteral("command"));
  scanner.Scan();
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenColon);
  scanner.Scan();
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenString);
  EXPECT(scanner.IsStringLiteral("Debugger.pause"));
  scanner.Scan();
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenRBrace);
  scanner.Scan();
  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenEOM);
}


TEST_CASE(JSON_SyntaxError) {
    const char* jobj = "{ \"id\": 5, "
                     "  \"command\" : \"Debugger.stop\""  // Missing comma.
                     "  \"params\" : { "
                     "    \"url\" : \"blah.dart\", "  // Missing comma.
                     "    \"line\": 111, "
                     "  },"
                     "  \"foo\": \"outer foo\", "
                     "}";
  JSONReader reader(jobj);
  bool found;

  found = reader.Seek("id");
  EXPECT(found);
  EXPECT_EQ(reader.Type(), JSONReader::kInteger);
  found = reader.Seek("params");
  EXPECT(!found);
  EXPECT(reader.Error());
  EXPECT_EQ(reader.Type(), JSONReader::kNone);
  EXPECT_EQ(0, reader.ValueLen());
  EXPECT(reader.ValueChars() == NULL);
}


TEST_CASE(JSON_JSONReader) {
  const char* jobj = "{ \"id\": 5, "
                     "  \"command\" : \"Debugger.setBreakpoint\","
                     "  \"params\" : { "
                     "    \"url\" : \"blah.dart\", "
                     "    \"foo\" : [null, 1, { }, \"bar\", true, false],"
                     "    \"line\": 111, "
                     "  },"
                     "  \"foo\": \"outer foo\", "
                     "}";

  JSONReader reader(jobj);
  bool found;

  found = reader.Seek("id");
  EXPECT(found);
  EXPECT_EQ(reader.Type(), JSONReader::kInteger);
  found = reader.Seek("foo");
  EXPECT(found);
  EXPECT_EQ(reader.Type(), JSONReader::kString);
  EXPECT(reader.IsStringLiteral("outer foo"));
  found = reader.Seek("line");
  EXPECT(!found);
  found = reader.Seek("params");
  EXPECT(found);
  EXPECT_EQ(reader.Type(), JSONReader::kObject);
  reader.Set(reader.ValueChars());
  found = reader.Seek("foo");
  EXPECT(found);
  EXPECT_EQ(reader.Type(), JSONReader::kArray);
  found = reader.Seek("non-existing");
  EXPECT(!found);
  found = reader.Seek("line");
  EXPECT(found);
  EXPECT_EQ(reader.Type(), JSONReader::kInteger);
}


TEST_CASE(JSON_TextBuffer) {
  TextBuffer w(5);  // Small enough to make buffer grow at least once.
  w.Printf("{ \"%s\" : %d", "length", 175);
  EXPECT_STREQ("{ \"length\" : 175", w.buf());
  w.Printf(", \"%s\" : \"%s\" }", "command", "stopIt");
  EXPECT_STREQ("{ \"length\" : 175, \"command\" : \"stopIt\" }", w.buf());

  JSONReader r(w.buf());
  bool found = r.Seek("command");
  EXPECT(found);
  EXPECT_EQ(r.Type(), JSONReader::kString);
  EXPECT(r.IsStringLiteral("stopIt"));
}


TEST_CASE(JSON_JSONStream_Primitives) {
  TextBuffer tb(256);
  JSONStream js(&tb);

  js.OpenObject();
  js.CloseObject();

  EXPECT_STREQ("{}", tb.buf());

  js.Clear();
  js.OpenArray();
  js.CloseArray();
  EXPECT_STREQ("[]", tb.buf());

  js.Clear();
  js.PrintValueBool(true);
  EXPECT_STREQ("true", tb.buf());

  js.Clear();
  js.PrintValueBool(false);
  EXPECT_STREQ("false", tb.buf());

  js.Clear();
  js.PrintValue((intptr_t)4);
  EXPECT_STREQ("4", tb.buf());

  js.Clear();
  js.PrintValue(1.0);
  EXPECT_STREQ("1.000000", tb.buf());

  js.Clear();
  js.PrintValue("hello");
  EXPECT_STREQ("\"hello\"", tb.buf());
}


TEST_CASE(JSON_JSONStream_Array) {
  TextBuffer tb(256);
  JSONStream js(&tb);
  js.Clear();
  js.OpenArray();
  js.PrintValueBool(true);
  js.PrintValueBool(false);
  js.CloseArray();
  EXPECT_STREQ("[true,false]", tb.buf());
}


TEST_CASE(JSON_JSONStream_Object) {
  TextBuffer tb(256);
  JSONStream js(&tb);
  js.Clear();
  js.OpenObject();
  js.PrintProperty("key1", "a");
  js.PrintProperty("key2", "b");
  js.CloseObject();
  EXPECT_STREQ("{\"key1\":\"a\",\"key2\":\"b\"}", tb.buf());
}

TEST_CASE(JSON_JSONStream_NestedObject) {
  TextBuffer tb(256);
  JSONStream js(&tb);
  js.OpenObject();
  js.OpenObject("key");
  js.PrintProperty("key1", "d");
  js.CloseObject();
  js.CloseObject();
  EXPECT_STREQ("{\"key\":{\"key1\":\"d\"}}", tb.buf());
}


TEST_CASE(JSON_JSONStream_ObjectArray) {
  TextBuffer tb(256);
  JSONStream js(&tb);
  js.OpenArray();
  js.OpenObject();
  js.PrintProperty("key", "e");
  js.CloseObject();
  js.OpenObject();
  js.PrintProperty("yek", "f");
  js.CloseObject();
  js.CloseArray();
  EXPECT_STREQ("[{\"key\":\"e\"},{\"yek\":\"f\"}]", tb.buf());
}


TEST_CASE(JSON_JSONStream_ArrayArray) {
  TextBuffer tb(256);
  JSONStream js(&tb);
  js.OpenArray();
  js.OpenArray();
  js.PrintValue((intptr_t)4);
  js.CloseArray();
  js.OpenArray();
  js.PrintValueBool(false);
  js.CloseArray();
  js.CloseArray();
  EXPECT_STREQ("[[4],[false]]", tb.buf());
}


TEST_CASE(JSON_JSONStream_DartObject) {
  TextBuffer tb(256);
  JSONStream js(&tb);
  js.OpenArray();
  js.PrintValue(Object::Handle(Object::null()));
  js.OpenObject();
  js.PrintProperty("object_key", Object::Handle(Object::null()));
  js.CloseArray();
  EXPECT_STREQ("[{\"type\":\"null\"},{\"object_key\":{\"type\":\"null\"}]",
               tb.buf());
}


}  // namespace dart
