/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/strings/json.h"

#include <errno.h>
#include <limits.h>
#include <stdlib.h>

#include "absl/strings/string_view.h"
#include "rtc_base/string_encode.h"

namespace webrtc {

bool GetStringFromJson(const Json::Value& in, std::string* out) {
  if (!in.isString()) {
    if (in.isBool()) {
      *out = BoolToString(in.asBool());
    } else if (in.isInt()) {
      *out = absl::StrCat(in.asInt());
    } else if (in.isUInt()) {
      *out = absl::StrCat(in.asUInt());
    } else if (in.isDouble()) {
      *out = absl::StrCat(in.asDouble());
    } else {
      return false;
    }
  } else {
    *out = in.asString();
  }
  return true;
}

bool GetIntFromJson(const Json::Value& in, int* out) {
  bool ret;
  if (!in.isString()) {
    ret = in.isConvertibleTo(Json::intValue);
    if (ret) {
      *out = in.asInt();
    }
  } else {
    long val;  // NOLINT
    const char* c_str = in.asCString();
    char* end_ptr;
    errno = 0;
    val = strtol(c_str, &end_ptr, 10);  // NOLINT
    ret = (end_ptr != c_str && *end_ptr == '\0' && !errno && val >= INT_MIN &&
           val <= INT_MAX);
    *out = val;
  }
  return ret;
}

bool GetUIntFromJson(const Json::Value& in, unsigned int* out) {
  bool ret;
  if (!in.isString()) {
    ret = in.isConvertibleTo(Json::uintValue);
    if (ret) {
      *out = in.asUInt();
    }
  } else {
    unsigned long val;  // NOLINT
    const char* c_str = in.asCString();
    char* end_ptr;
    errno = 0;
    val = strtoul(c_str, &end_ptr, 10);  // NOLINT
    ret = (end_ptr != c_str && *end_ptr == '\0' && !errno && val <= UINT_MAX);
    *out = val;
  }
  return ret;
}

bool GetBoolFromJson(const Json::Value& in, bool* out) {
  bool ret;
  if (!in.isString()) {
    ret = in.isConvertibleTo(Json::booleanValue);
    if (ret) {
      *out = in.asBool();
    }
  } else {
    if (in.asString() == "true") {
      *out = true;
      ret = true;
    } else if (in.asString() == "false") {
      *out = false;
      ret = true;
    } else {
      ret = false;
    }
  }
  return ret;
}

bool GetDoubleFromJson(const Json::Value& in, double* out) {
  bool ret;
  if (!in.isString()) {
    ret = in.isConvertibleTo(Json::realValue);
    if (ret) {
      *out = in.asDouble();
    }
  } else {
    double val;
    const char* c_str = in.asCString();
    char* end_ptr;
    errno = 0;
    val = strtod(c_str, &end_ptr);
    ret = (end_ptr != c_str && *end_ptr == '\0' && !errno);
    *out = val;
  }
  return ret;
}

namespace {
template <typename T>
bool JsonArrayToVector(const Json::Value& value,
                       bool (*getter)(const Json::Value& in, T* out),
                       std::vector<T>* vec) {
  vec->clear();
  if (!value.isArray()) {
    return false;
  }

  for (Json::Value::ArrayIndex i = 0; i < value.size(); ++i) {
    T val;
    if (!getter(value[i], &val)) {
      return false;
    }
    vec->push_back(val);
  }

  return true;
}
// Trivial getter helper
bool GetValueFromJson(const Json::Value& in, Json::Value* out) {
  *out = in;
  return true;
}
}  // unnamed namespace

bool JsonArrayToValueVector(const Json::Value& in,
                            std::vector<Json::Value>* out) {
  return JsonArrayToVector(in, GetValueFromJson, out);
}

bool JsonArrayToIntVector(const Json::Value& in, std::vector<int>* out) {
  return JsonArrayToVector(in, GetIntFromJson, out);
}

bool JsonArrayToUIntVector(const Json::Value& in,
                           std::vector<unsigned int>* out) {
  return JsonArrayToVector(in, GetUIntFromJson, out);
}

bool JsonArrayToStringVector(const Json::Value& in,
                             std::vector<std::string>* out) {
  return JsonArrayToVector(in, GetStringFromJson, out);
}

bool JsonArrayToBoolVector(const Json::Value& in, std::vector<bool>* out) {
  return JsonArrayToVector(in, GetBoolFromJson, out);
}

bool JsonArrayToDoubleVector(const Json::Value& in, std::vector<double>* out) {
  return JsonArrayToVector(in, GetDoubleFromJson, out);
}

namespace {
template <typename T>
Json::Value VectorToJsonArray(const std::vector<T>& vec) {
  Json::Value result(Json::arrayValue);
  for (size_t i = 0; i < vec.size(); ++i) {
    result.append(Json::Value(vec[i]));
  }
  return result;
}
}  // unnamed namespace

Json::Value ValueVectorToJsonArray(const std::vector<Json::Value>& in) {
  return VectorToJsonArray(in);
}

Json::Value IntVectorToJsonArray(const std::vector<int>& in) {
  return VectorToJsonArray(in);
}

Json::Value UIntVectorToJsonArray(const std::vector<unsigned int>& in) {
  return VectorToJsonArray(in);
}

Json::Value StringVectorToJsonArray(const std::vector<std::string>& in) {
  return VectorToJsonArray(in);
}

Json::Value BoolVectorToJsonArray(const std::vector<bool>& in) {
  return VectorToJsonArray(in);
}

Json::Value DoubleVectorToJsonArray(const std::vector<double>& in) {
  return VectorToJsonArray(in);
}

bool GetValueFromJsonArray(const Json::Value& in, size_t n, Json::Value* out) {
  if (!in.isArray() || !in.isValidIndex(static_cast<int>(n))) {
    return false;
  }

  *out = in[static_cast<Json::Value::ArrayIndex>(n)];
  return true;
}

bool GetIntFromJsonArray(const Json::Value& in, size_t n, int* out) {
  Json::Value x;
  return GetValueFromJsonArray(in, n, &x) && GetIntFromJson(x, out);
}

bool GetUIntFromJsonArray(const Json::Value& in, size_t n, unsigned int* out) {
  Json::Value x;
  return GetValueFromJsonArray(in, n, &x) && GetUIntFromJson(x, out);
}

bool GetStringFromJsonArray(const Json::Value& in, size_t n, std::string* out) {
  Json::Value x;
  return GetValueFromJsonArray(in, n, &x) && GetStringFromJson(x, out);
}

bool GetBoolFromJsonArray(const Json::Value& in, size_t n, bool* out) {
  Json::Value x;
  return GetValueFromJsonArray(in, n, &x) && GetBoolFromJson(x, out);
}

bool GetDoubleFromJsonArray(const Json::Value& in, size_t n, double* out) {
  Json::Value x;
  return GetValueFromJsonArray(in, n, &x) && GetDoubleFromJson(x, out);
}

bool GetValueFromJsonObject(const Json::Value& in,
                            absl::string_view k,
                            Json::Value* out) {
  std::string k_str(k);
  if (!in.isObject() || !in.isMember(k_str)) {
    return false;
  }

  *out = in[k_str];
  return true;
}

bool GetIntFromJsonObject(const Json::Value& in,
                          absl::string_view k,
                          int* out) {
  Json::Value x;
  return GetValueFromJsonObject(in, k, &x) && GetIntFromJson(x, out);
}

bool GetUIntFromJsonObject(const Json::Value& in,
                           absl::string_view k,
                           unsigned int* out) {
  Json::Value x;
  return GetValueFromJsonObject(in, k, &x) && GetUIntFromJson(x, out);
}

bool GetStringFromJsonObject(const Json::Value& in,
                             absl::string_view k,
                             std::string* out) {
  Json::Value x;
  return GetValueFromJsonObject(in, k, &x) && GetStringFromJson(x, out);
}

bool GetBoolFromJsonObject(const Json::Value& in,
                           absl::string_view k,
                           bool* out) {
  Json::Value x;
  return GetValueFromJsonObject(in, k, &x) && GetBoolFromJson(x, out);
}

bool GetDoubleFromJsonObject(const Json::Value& in,
                             absl::string_view k,
                             double* out) {
  Json::Value x;
  return GetValueFromJsonObject(in, k, &x) && GetDoubleFromJson(x, out);
}

std::string JsonValueToString(const Json::Value& json) {
  Json::StreamWriterBuilder builder;
  std::string output = Json::writeString(builder, json);
  return output.substr(0, output.size() - 1);  // trim trailing newline
}

}  // namespace webrtc
