// Copyright 2019 the V8 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.

#ifndef V8_TORQUE_LS_JSON_H_
#define V8_TORQUE_LS_JSON_H_

#include <map>
#include <string>
#include <vector>

#include "src/base/logging.h"
#include "src/base/template-utils.h"

namespace v8 {
namespace internal {
namespace torque {
namespace ls {

struct JsonValue;

using JsonObject = std::map<std::string, JsonValue>;
using JsonArray = std::vector<JsonValue>;

struct JsonValue {
 public:
  enum { OBJECT, ARRAY, STRING, NUMBER, BOOL, IS_NULL } tag;

  // JsonValues can only be moved, not copied.
  JsonValue() V8_NOEXCEPT = default;
  constexpr JsonValue(const JsonValue& other) = delete;
  JsonValue& operator=(const JsonValue& other) = delete;

  JsonValue(JsonValue&& other) V8_NOEXCEPT = default;
  JsonValue& operator=(JsonValue&& other) V8_NOEXCEPT = default;

  static JsonValue From(double number) {
    JsonValue result;
    result.tag = JsonValue::NUMBER;
    result.number_ = number;
    return result;
  }

  static JsonValue From(JsonObject object) {
    JsonValue result;
    result.tag = JsonValue::OBJECT;
    result.object_ = base::make_unique<JsonObject>(std::move(object));
    return result;
  }

  static JsonValue From(bool b) {
    JsonValue result;
    result.tag = JsonValue::BOOL;
    result.flag_ = b;
    return result;
  }

  static JsonValue From(const std::string& string) {
    JsonValue result;
    result.tag = JsonValue::STRING;
    result.string_ = string;
    return result;
  }

  static JsonValue From(JsonArray array) {
    JsonValue result;
    result.tag = JsonValue::ARRAY;
    result.array_ = base::make_unique<JsonArray>(std::move(array));
    return result;
  }

  static JsonValue JsonNull() {
    JsonValue result;
    result.tag = JsonValue::IS_NULL;
    return result;
  }

  bool IsNumber() const { return tag == NUMBER; }
  double ToNumber() const {
    CHECK(IsNumber());
    return number_;
  }

  bool IsBool() const { return tag == BOOL; }
  bool ToBool() const {
    CHECK(IsBool());
    return flag_;
  }

  bool IsString() const { return tag == STRING; }
  const std::string& ToString() const {
    CHECK(IsString());
    return string_;
  }

  bool IsObject() const { return object_ && tag == OBJECT; }
  const JsonObject& ToObject() const {
    CHECK(IsObject());
    return *object_;
  }
  JsonObject& ToObject() {
    CHECK(IsObject());
    return *object_;
  }

  bool IsArray() const { return array_ && tag == ARRAY; }
  const JsonArray& ToArray() const {
    CHECK(IsArray());
    return *array_;
  }
  JsonArray& ToArray() {
    CHECK(IsArray());
    return *array_;
  }

 private:
  double number_ = 0;
  bool flag_ = false;
  std::string string_;
  std::unique_ptr<JsonObject> object_;
  std::unique_ptr<JsonArray> array_;
};

std::string SerializeToString(const JsonValue& value);

}  // namespace ls
}  // namespace torque
}  // namespace internal
}  // namespace v8

#endif  // V8_TORQUE_LS_JSON_H_
