// 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::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(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::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_;
}

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

  switch (type_) {
    case Type::UNSIGNED:
    case Type::NEGATIVE:
      integer_value_ = that.integer_value_;
      return;
    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:
      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
