// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/test/values_test_util.h"

#include <ostream>
#include <utility>

#include "base/json/json_reader.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

void ExpectDictBooleanValue(bool expected_value,
                            const DictionaryValue& value,
                            const std::string& key) {
  bool boolean_value = false;
  EXPECT_TRUE(value.GetBoolean(key, &boolean_value)) << key;
  EXPECT_EQ(expected_value, boolean_value) << key;
}

void ExpectDictDictionaryValue(const DictionaryValue& expected_value,
                               const DictionaryValue& value,
                               const std::string& key) {
  const DictionaryValue* dict_value = nullptr;
  EXPECT_TRUE(value.GetDictionary(key, &dict_value)) << key;
  EXPECT_EQ(expected_value, *dict_value) << key;
}

void ExpectDictIntegerValue(int expected_value,
                            const DictionaryValue& value,
                            const std::string& key) {
  int integer_value = 0;
  EXPECT_TRUE(value.GetInteger(key, &integer_value)) << key;
  EXPECT_EQ(expected_value, integer_value) << key;
}

void ExpectDictListValue(const ListValue& expected_value,
                         const DictionaryValue& value,
                         const std::string& key) {
  const ListValue* list_value = nullptr;
  EXPECT_TRUE(value.GetList(key, &list_value)) << key;
  EXPECT_EQ(expected_value, *list_value) << key;
}

void ExpectDictStringValue(const std::string& expected_value,
                           const DictionaryValue& value,
                           const std::string& key) {
  std::string string_value;
  EXPECT_TRUE(value.GetString(key, &string_value)) << key;
  EXPECT_EQ(expected_value, string_value) << key;
}

void ExpectStringValue(const std::string& expected_str, const Value& actual) {
  EXPECT_EQ(Value::Type::STRING, actual.type());
  EXPECT_EQ(expected_str, actual.GetString());
}

namespace test {

IsJsonMatcher::IsJsonMatcher(base::StringPiece json)
    : expected_value_(test::ParseJson(json)) {}

IsJsonMatcher::IsJsonMatcher(const base::Value& value)
    : expected_value_(value.Clone()) {}

IsJsonMatcher::IsJsonMatcher(const IsJsonMatcher& other)
    : expected_value_(other.expected_value_.Clone()) {}

IsJsonMatcher::~IsJsonMatcher() = default;

bool IsJsonMatcher::MatchAndExplain(
    base::StringPiece json,
    testing::MatchResultListener* listener) const {
  // This is almost the same logic as ParseJson, but the parser uses stricter
  // options for JSON data that is assumed to be generated by the code under
  // test rather than written by hand as part of a unit test.
  JSONReader::ValueWithError ret =
      JSONReader::ReadAndReturnValueWithError(json, JSON_PARSE_RFC);
  if (!ret.value) {
    *listener << "Failed to parse \"" << json << "\": " << ret.error_message;
    return false;
  }
  return MatchAndExplain(*ret.value, listener);
}

bool IsJsonMatcher::MatchAndExplain(
    const base::Value& value,
    testing::MatchResultListener* /* listener */) const {
  return expected_value_ == value;
}

void IsJsonMatcher::DescribeTo(std::ostream* os) const {
  *os << "is the JSON value " << expected_value_;
}

void IsJsonMatcher::DescribeNegationTo(std::ostream* os) const {
  *os << "is not the JSON value " << expected_value_;
}

Value ParseJson(StringPiece json) {
  JSONReader::ValueWithError result =
      JSONReader::ReadAndReturnValueWithError(json, JSON_ALLOW_TRAILING_COMMAS);
  if (!result.value) {
    ADD_FAILURE() << "Failed to parse \"" << json
                  << "\": " << result.error_message;
    return Value();
  }
  return std::move(result.value.value());
}

std::unique_ptr<Value> ParseJsonDeprecated(StringPiece json) {
  return Value::ToUniquePtrValue(ParseJson(json));
}

}  // namespace test
}  // namespace base
