// Copyright 2017 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 "components/cbor/values.h"

#include <new>
#include <utility>

#include "base/numerics/safe_conversions.h"
#include "base/strings/string_util.h"
#include "components/cbor/constants.h"

namespace cbor {

Value::Value() noexcept : type_(Type::NONE) {}

Value::Value(Value&& that) noexcept {
  InternalMoveConstructFrom(std::move(that));
}

Value::Value(Type type) : type_(type) {
  // Initialize with the default value.
  switch (type_) {
    case Type::UNSIGNED:
    case Type::NEGATIVE:
      integer_value_ = 0;
      return;
    case Type::INVALID_UTF8:
    case Type::BYTE_STRING:
      new (&bytestring_value_) BinaryValue();
      return;
    case Type::STRING:
      new (&string_value_) std::string();
      return;
    case Type::ARRAY:
      new (&array_value_) ArrayValue();
      return;
    case Type::MAP:
      new (&map_value_) MapValue();
      return;
    case Type::TAG:
      NOTREACHED() << constants::kUnsupportedMajorType;
      return;
    case Type::SIMPLE_VALUE:
      simple_value_ = Value::SimpleValue::UNDEFINED;
      return;
    case Type::NONE:
      return;
  }
  NOTREACHED();
}

Value::Value(SimpleValue in_simple)
    : type_(Type::SIMPLE_VALUE), simple_value_(in_simple) {
  CHECK(static_cast<int>(in_simple) >= 20 && static_cast<int>(in_simple) <= 23);
}

Value::Value(bool boolean_value) : type_(Type::SIMPLE_VALUE) {
  simple_value_ = boolean_value ? Value::SimpleValue::TRUE_VALUE
                                : Value::SimpleValue::FALSE_VALUE;
}

Value::Value(int integer_value)
    : Value(base::checked_cast<int64_t>(integer_value)) {}

Value::Value(int64_t integer_value) : integer_value_(integer_value) {
  type_ = integer_value >= 0 ? Type::UNSIGNED : Type::NEGATIVE;
}

Value::Value(base::span<const uint8_t> in_bytes)
    : type_(Type::BYTE_STRING),
      bytestring_value_(in_bytes.begin(), in_bytes.end()) {}

Value::Value(base::span<const uint8_t> in_bytes, Type type)
    : type_(type), bytestring_value_(in_bytes.begin(), in_bytes.end()) {
  DCHECK(type_ == Type::BYTE_STRING || type_ == Type::INVALID_UTF8);
}

Value::Value(BinaryValue&& in_bytes) noexcept
    : type_(Type::BYTE_STRING), bytestring_value_(std::move(in_bytes)) {}

Value::Value(const char* in_string, Type type)
    : Value(base::StringPiece(in_string), type) {}

Value::Value(std::string&& in_string, Type type) noexcept : type_(type) {
  switch (type_) {
    case Type::STRING:
      new (&string_value_) std::string();
      string_value_ = std::move(in_string);
      DCHECK(base::IsStringUTF8(string_value_));
      break;
    case Type::BYTE_STRING:
      new (&bytestring_value_) BinaryValue();
      bytestring_value_ = BinaryValue(in_string.begin(), in_string.end());
      break;
    default:
      NOTREACHED();
  }
}

Value::Value(base::StringPiece in_string, Type type) : type_(type) {
  switch (type_) {
    case Type::STRING:
      new (&string_value_) std::string();
      string_value_ = in_string.as_string();
      DCHECK(base::IsStringUTF8(string_value_));
      break;
    case Type::BYTE_STRING:
      new (&bytestring_value_) BinaryValue();
      bytestring_value_ = BinaryValue(in_string.begin(), in_string.end());
      break;
    default:
      NOTREACHED();
  }
}

Value::Value(const ArrayValue& in_array) : type_(Type::ARRAY), array_value_() {
  array_value_.reserve(in_array.size());
  for (const auto& val : in_array)
    array_value_.emplace_back(val.Clone());
}

Value::Value(ArrayValue&& in_array) noexcept
    : type_(Type::ARRAY), array_value_(std::move(in_array)) {}

Value::Value(const MapValue& in_map) : type_(Type::MAP), map_value_() {
  map_value_.reserve(in_map.size());
  for (const auto& it : in_map)
    map_value_.emplace_hint(map_value_.end(), it.first.Clone(),
                            it.second.Clone());
}

Value::Value(MapValue&& in_map) noexcept
    : type_(Type::MAP), map_value_(std::move(in_map)) {}

Value& Value::operator=(Value&& that) noexcept {
  InternalCleanup();
  InternalMoveConstructFrom(std::move(that));

  return *this;
}

Value::~Value() {
  InternalCleanup();
}

Value Value::Clone() const {
  switch (type_) {
    case Type::NONE:
      return Value();
    case Type::INVALID_UTF8:
      return Value(bytestring_value_, Type::INVALID_UTF8);
    case Type::UNSIGNED:
    case Type::NEGATIVE:
      return Value(integer_value_);
    case Type::BYTE_STRING:
      return Value(bytestring_value_);
    case Type::STRING:
      return Value(string_value_);
    case Type::ARRAY:
      return Value(array_value_);
    case Type::MAP:
      return Value(map_value_);
    case Type::TAG:
      NOTREACHED() << constants::kUnsupportedMajorType;
      return Value();
    case Type::SIMPLE_VALUE:
      return Value(simple_value_);
  }

  NOTREACHED();
  return Value();
}

Value::SimpleValue Value::GetSimpleValue() const {
  CHECK(is_simple());
  return simple_value_;
}

bool Value::GetBool() const {
  CHECK(is_bool());
  return simple_value_ == SimpleValue::TRUE_VALUE;
}

const int64_t& Value::GetInteger() const {
  CHECK(is_integer());
  return integer_value_;
}

const int64_t& Value::GetUnsigned() const {
  CHECK(is_unsigned());
  CHECK_GE(integer_value_, 0);
  return integer_value_;
}

const int64_t& Value::GetNegative() const {
  CHECK(is_negative());
  CHECK_LT(integer_value_, 0);
  return integer_value_;
}

const std::string& Value::GetString() const {
  CHECK(is_string());
  return string_value_;
}

const Value::BinaryValue& Value::GetBytestring() const {
  CHECK(is_bytestring());
  return bytestring_value_;
}

base::StringPiece Value::GetBytestringAsString() const {
  CHECK(is_bytestring());
  const auto& bytestring_value = GetBytestring();
  return base::StringPiece(
      reinterpret_cast<const char*>(bytestring_value.data()),
      bytestring_value.size());
}

const Value::ArrayValue& Value::GetArray() const {
  CHECK(is_array());
  return array_value_;
}

const Value::MapValue& Value::GetMap() const {
  CHECK(is_map());
  return map_value_;
}

const Value::BinaryValue& Value::GetInvalidUTF8() const {
  CHECK(is_invalid_utf8());
  return bytestring_value_;
}

void Value::InternalMoveConstructFrom(Value&& that) {
  type_ = that.type_;

  switch (type_) {
    case Type::UNSIGNED:
    case Type::NEGATIVE:
      integer_value_ = that.integer_value_;
      return;
    case Type::INVALID_UTF8:
    case Type::BYTE_STRING:
      new (&bytestring_value_) BinaryValue(std::move(that.bytestring_value_));
      return;
    case Type::STRING:
      new (&string_value_) std::string(std::move(that.string_value_));
      return;
    case Type::ARRAY:
      new (&array_value_) ArrayValue(std::move(that.array_value_));
      return;
    case Type::MAP:
      new (&map_value_) MapValue(std::move(that.map_value_));
      return;
    case Type::TAG:
      NOTREACHED() << constants::kUnsupportedMajorType;
      return;
    case Type::SIMPLE_VALUE:
      simple_value_ = that.simple_value_;
      return;
    case Type::NONE:
      return;
  }
  NOTREACHED();
}

void Value::InternalCleanup() {
  switch (type_) {
    case Type::BYTE_STRING:
    case Type::INVALID_UTF8:
      bytestring_value_.~BinaryValue();
      break;
    case Type::STRING:
      string_value_.~basic_string();
      break;
    case Type::ARRAY:
      array_value_.~ArrayValue();
      break;
    case Type::MAP:
      map_value_.~MapValue();
      break;
    case Type::TAG:
      NOTREACHED() << constants::kUnsupportedMajorType;
      break;
    case Type::NONE:
    case Type::UNSIGNED:
    case Type::NEGATIVE:
    case Type::SIMPLE_VALUE:
      break;
  }
  type_ = Type::NONE;
}

}  // namespace cbor
