// Copyright 2017 The Fuchsia 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 "uuid.h"

#include <endian.h>
#include <zircon/assert.h>

#include <cinttypes>

#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/lib/fxl/strings/string_number_conversions.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace bt {
namespace {

// Format string that can be passed to sscanf. This allows sscanf to convert
// each octet into a uint8_t.
constexpr char kScanUuidFormatString[] =
    "%2" SCNx8 "%2" SCNx8 "%2" SCNx8 "%2" SCNx8
    "-"
    "%2" SCNx8 "%2" SCNx8
    "-"
    "%2" SCNx8 "%2" SCNx8
    "-"
    "%2" SCNx8 "%2" SCNx8
    "-"
    "%2" SCNx8 "%2" SCNx8 "%2" SCNx8 "%2" SCNx8 "%2" SCNx8 "%2" SCNx8;

// Size in bytes of the three valid lengths of UUIDs
constexpr size_t k16BitSize = 2;
constexpr size_t k32BitSize = 4;
constexpr size_t k128BitSize = 16;

// Parses the contents of a |uuid_string| and returns the result in |out_bytes|.
// Returns false if |uuid_string| does not represent a valid UUID.
// TODO(armansito): After having used UUID in camel-case words all over the
// place, I've decided that it sucks. I'm explicitly naming this using the
// "Uuid" style as a reminder to fix style elsewhere.
bool ParseUuidString(const std::string& uuid_string, UInt128* out_bytes) {
  ZX_DEBUG_ASSERT(out_bytes);

  if (uuid_string.length() == 4) {
    // Possibly a 16-bit short UUID, parse it in context of the Base UUID.
    return ParseUuidString("0000" + uuid_string + "-0000-1000-8000-00805F9B34FB", out_bytes);
  }

  // This is a 36 character string, including 4 "-" characters and two
  // characters for each of the 16-octets that form the 128-bit UUID.
  if (uuid_string.length() != 36)
    return false;

  int result = std::sscanf(uuid_string.c_str(), kScanUuidFormatString, out_bytes->data() + 15,
                           out_bytes->data() + 14, out_bytes->data() + 13, out_bytes->data() + 12,
                           out_bytes->data() + 11, out_bytes->data() + 10, out_bytes->data() + 9,
                           out_bytes->data() + 8, out_bytes->data() + 7, out_bytes->data() + 6,
                           out_bytes->data() + 5, out_bytes->data() + 4, out_bytes->data() + 3,
                           out_bytes->data() + 2, out_bytes->data() + 1, out_bytes->data());

  return (result > 0) && (static_cast<size_t>(result) == out_bytes->size());
}

}  // namespace

// These constexpr static members need to be declared here for linkage as they
// get used in non-constexpr contexts as well:
// static
constexpr UInt128 UUID::kBaseUuid;
constexpr size_t UUID::kBaseOffset;

// static
bool UUID::FromBytes(const ByteBuffer& bytes, UUID* out_uuid) {
  switch (bytes.size()) {
    case k16BitSize:
      *out_uuid = UUID(le16toh(*reinterpret_cast<const uint16_t*>(bytes.data())));
      return true;
    case k32BitSize:
      *out_uuid = UUID(le32toh(*reinterpret_cast<const uint32_t*>(bytes.data())));
      return true;
    case k128BitSize:
      *out_uuid = UUID(*reinterpret_cast<const UInt128*>(bytes.data()));
      return true;
  }

  return false;
}

UUID::UUID() : type_(Type::k128Bit) { value_.fill(0); }

bool UUID::operator==(const UUID& uuid) const { return value_ == uuid.value_; }

bool UUID::operator==(uint16_t uuid16) const {
  if (type_ == Type::k16Bit)
    return uuid16 == ValueAs16Bit();

  // Quick conversion is not possible; compare as two 128-bit UUIDs.
  return *this == UUID(uuid16);
}

bool UUID::operator==(uint32_t uuid32) const {
  if (type_ != Type::k128Bit)
    return uuid32 == ValueAs32Bit();

  // Quick conversion is not possible; compare as two 128-bit UUIDs.
  return *this == UUID(uuid32);
}

bool UUID::operator==(const UInt128& uuid128) const { return value_ == uuid128; }

bool UUID::CompareBytes(const ByteBuffer& bytes) const {
  switch (bytes.size()) {
    case k16BitSize:
      return (*this == le16toh(*reinterpret_cast<const uint16_t*>(bytes.data())));
    case k32BitSize:
      return (*this == le32toh(*reinterpret_cast<const uint32_t*>(bytes.data())));
    case k128BitSize:
      return (*this == *reinterpret_cast<const UInt128*>(bytes.data()));
  }

  return false;
}

std::string UUID::ToString() const {
  return fxl::StringPrintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                           value_[15], value_[14], value_[13], value_[12], value_[11], value_[10],
                           value_[9], value_[8], value_[7], value_[6], value_[5], value_[4],
                           value_[3], value_[2], value_[1], value_[0]);
}

size_t UUID::CompactSize(bool allow_32bit) const {
  switch (type_) {
    case Type::k16Bit:
      return k16BitSize;
    case Type::k32Bit:
      if (allow_32bit)
        return k32BitSize;

      // Fall through if 32-bit UUIDs are not allowed.
    case Type::k128Bit:
      return k128BitSize;
  };

  return 0;
}

size_t UUID::ToBytes(MutableByteBuffer* bytes, bool allow_32bit) const {
  size_t size = CompactSize(allow_32bit);
  size_t offset = (size == k128BitSize) ? 0u : kBaseOffset;
  bytes->Write(value_.data() + offset, size);
  return size;
}

const BufferView UUID::CompactView(bool allow_32bit) const {
  size_t size = CompactSize(allow_32bit);
  size_t offset = (size == k128BitSize) ? 0u : kBaseOffset;
  return BufferView(value_.data() + offset, size);
}

std::size_t UUID::Hash() const {
  ZX_DEBUG_ASSERT(sizeof(value_) % sizeof(size_t) == 0);
  size_t hash = 0;
  for (size_t i = 0; i < (sizeof(value_) / sizeof(size_t)); i++) {
    hash ^= *reinterpret_cast<const size_t*>(value_.data() + (i * sizeof(size_t)));
  }
  return hash;
}

std::optional<uint16_t> UUID::As16Bit() const {
  std::optional<uint16_t> ret;
  if (type_ == Type::k16Bit) {
    ret = ValueAs16Bit();
  }
  return ret;
}

uint16_t UUID::ValueAs16Bit() const {
  ZX_DEBUG_ASSERT(type_ == Type::k16Bit);

  return le16toh(*reinterpret_cast<const uint16_t*>(value_.data() + kBaseOffset));
}

uint32_t UUID::ValueAs32Bit() const {
  ZX_DEBUG_ASSERT(type_ != Type::k128Bit);

  return le32toh(*reinterpret_cast<const uint32_t*>(value_.data() + kBaseOffset));
}

bool IsStringValidUuid(const std::string& uuid_string) {
  UInt128 bytes;
  return ParseUuidString(uuid_string, &bytes);
}

bool StringToUuid(const std::string& uuid_string, UUID* out_uuid) {
  ZX_DEBUG_ASSERT(out_uuid);

  UInt128 bytes;
  if (!ParseUuidString(uuid_string, &bytes))
    return false;

  *out_uuid = UUID(bytes);
  return true;
}

}  // namespace bt
