#ifndef _JSON_OBJECT_H_
#define _JSON_OBJECT_H_

#include "json_array.h"

namespace base {

std::string rapidjson_to_string(const rapidjson::Document& doc);
std::string rapidjson_to_pretty_string(const rapidjson::Document& doc);

class JSONArray;
class JSONObject {
public:
  JSONObject();
  virtual ~JSONObject();
  JSONObject(const rapidjson::Value& value);
  JSONObject(const rapidjson::Value::Object& obj);
  JSONObject(const rapidjson::Value::ConstObject& obj);
  JSONObject(JSONObject&& obj);
  JSONObject(const JSONObject& obj);

  JSONObject& Put(const std::string& name, int32_t v);

  JSONObject& Put(const std::string& name, uint32_t v);

  JSONObject& Put(const std::string& name, int64_t v);

  JSONObject& Put(const std::string& name, uint64_t v);

  JSONObject& Put(const std::string& name, const std::string& v);

  JSONObject& Put(const std::string& name, const JSONObject& v);
  JSONObject& Put(const std::string& name, const JSONArray& v);

  bool ParseObject(const std::string& json_str);

  bool ParseObjectFromFile(const std::string& path);

  std::string ToString() const;
  std::string ToPrettyString() const;

  /**
   * if not found, throw std::string
   */
  int GetInt(const std::string& name);

  /**
   * if not found, throw std::string
   */
  uint32_t GetUint(const std::string& name);

  uint32_t GetUint(const std::string& name, uint32_t default_value);

  int GetInt(const std::string& name, int default_value);

  int64_t GetInt64(const std::string& name, int64_t default_value);

  /**
   * if not found, throw std::string
   */
  std::string GetString(const std::string& name);

  std::string GetString(const std::string& name,
      const std::string& default_value);

  bool GetBool(const std::string& name, bool default_value);

  /**
   * if not found, return empty array
   */
  JSONArray GetArray(const std::string& name) const;

  /**
   * if not found, return empty object
   */
  JSONObject GetObject(const std::string& name);

private:
  friend class JSONArray;
  rapidjson::Document doc_;
};

}
/* namespace json */

#endif
