// 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/cbor_writer.h"

#include <string>

#include "base/numerics/safe_conversions.h"
#include "base/strings/string_piece.h"
#include "components/cbor/cbor_constants.h"

namespace cbor {

Writer::~Writer() {}

// static
base::Optional<std::vector<uint8_t>> Writer::Write(const Value& node,
                                                   size_t max_nesting_level) {
  std::vector<uint8_t> cbor;
  Writer writer(&cbor);
  if (writer.EncodeCBOR(node, base::checked_cast<int>(max_nesting_level)))
    return cbor;
  return base::nullopt;
}

Writer::Writer(std::vector<uint8_t>* cbor) : encoded_cbor_(cbor) {}

bool Writer::EncodeCBOR(const Value& node, int max_nesting_level) {
  if (max_nesting_level < 0)
    return false;

  switch (node.type()) {
    case Value::Type::NONE: {
      StartItem(Value::Type::BYTE_STRING, 0);
      return true;
    }

    // Represents unsigned integers.
    case Value::Type::UNSIGNED: {
      int64_t value = node.GetUnsigned();
      StartItem(Value::Type::UNSIGNED, static_cast<uint64_t>(value));
      return true;
    }

    // Represents negative integers.
    case Value::Type::NEGATIVE: {
      int64_t value = node.GetNegative();
      StartItem(Value::Type::NEGATIVE, static_cast<uint64_t>(-(value + 1)));
      return true;
    }

    // Represents a byte string.
    case Value::Type::BYTE_STRING: {
      const Value::BinaryValue& bytes = node.GetBytestring();
      StartItem(Value::Type::BYTE_STRING,
                base::strict_cast<uint64_t>(bytes.size()));
      // Add the bytes.
      encoded_cbor_->insert(encoded_cbor_->end(), bytes.begin(), bytes.end());
      return true;
    }

    case Value::Type::STRING: {
      base::StringPiece string = node.GetString();
      StartItem(Value::Type::STRING,
                base::strict_cast<uint64_t>(string.size()));

      // Add the characters.
      encoded_cbor_->insert(encoded_cbor_->end(), string.begin(), string.end());
      return true;
    }

    // Represents an array.
    case Value::Type::ARRAY: {
      const Value::ArrayValue& array = node.GetArray();
      StartItem(Value::Type::ARRAY, array.size());
      for (const auto& value : array) {
        if (!EncodeCBOR(value, max_nesting_level - 1))
          return false;
      }
      return true;
    }

    // Represents a map.
    case Value::Type::MAP: {
      const Value::MapValue& map = node.GetMap();
      StartItem(Value::Type::MAP, map.size());

      for (const auto& value : map) {
        if (!EncodeCBOR(value.first, max_nesting_level - 1))
          return false;
        if (!EncodeCBOR(value.second, max_nesting_level - 1))
          return false;
      }
      return true;
    }

    case Value::Type::TAG:
      NOTREACHED() << constants::kUnsupportedMajorType;
      return false;

    // Represents a simple value.
    case Value::Type::SIMPLE_VALUE: {
      const Value::SimpleValue simple_value = node.GetSimpleValue();
      StartItem(Value::Type::SIMPLE_VALUE,
                base::checked_cast<uint64_t>(simple_value));
      return true;
    }
  }

  // This is needed because, otherwise, MSVC complains that not all paths return
  // a value. We should be able to remove it once MSVC builders are gone.
  NOTREACHED();
  return false;
}

void Writer::StartItem(Value::Type type, uint64_t size) {
  encoded_cbor_->push_back(base::checked_cast<uint8_t>(
      static_cast<unsigned>(type) << constants::kMajorTypeBitShift));
  SetUint(size);
}

void Writer::SetAdditionalInformation(uint8_t additional_information) {
  DCHECK(!encoded_cbor_->empty());
  DCHECK_EQ(additional_information & constants::kAdditionalInformationMask,
            additional_information);
  encoded_cbor_->back() |=
      (additional_information & constants::kAdditionalInformationMask);
}

void Writer::SetUint(uint64_t value) {
  size_t count = GetNumUintBytes(value);
  int shift = -1;
  // Values under 24 are encoded directly in the initial byte.
  // Otherwise, the last 5 bits of the initial byte contains the length
  // of unsigned integer, which is encoded in following bytes.
  switch (count) {
    case 0:
      SetAdditionalInformation(base::checked_cast<uint8_t>(value));
      break;
    case 1:
      SetAdditionalInformation(constants::kAdditionalInformation1Byte);
      shift = 0;
      break;
    case 2:
      SetAdditionalInformation(constants::kAdditionalInformation2Bytes);
      shift = 1;
      break;
    case 4:
      SetAdditionalInformation(constants::kAdditionalInformation4Bytes);
      shift = 3;
      break;
    case 8:
      SetAdditionalInformation(constants::kAdditionalInformation8Bytes);
      shift = 7;
      break;
    default:
      NOTREACHED();
      break;
  }
  for (; shift >= 0; shift--) {
    encoded_cbor_->push_back(0xFF & (value >> (shift * 8)));
  }
}

size_t Writer::GetNumUintBytes(uint64_t value) {
  if (value < 24) {
    return 0;
  } else if (value <= 0xFF) {
    return 1;
  } else if (value <= 0xFFFF) {
    return 2;
  } else if (value <= 0xFFFFFFFF) {
    return 4;
  }
  return 8;
}

}  // namespace cbor
