#include "aos/uuid.h"

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <array>
#include <random>
#include <string_view>

#include "absl/flags/flag.h"
#include "absl/log/check.h"
#include "absl/log/log.h"

ABSL_FLAG(std::string, boot_uuid, "",
          "If set, override the boot UUID to have this value instead.");

namespace aos {
namespace {
void ToHex(const uint8_t *val, char *result, size_t count) {
  while (count > 0) {
    int upper = ((*val) >> 4) & 0xf;
    if (upper < 10) {
      result[0] = upper + '0';
    } else {
      result[0] = upper - 10 + 'a';
    }

    int lower = (*val) & 0xf;
    if (lower < 10) {
      result[1] = lower + '0';
    } else {
      result[1] = lower - 10 + 'a';
    }

    ++val;
    result += 2;
    --count;
  }
}

void FromHex(const char *val, uint8_t *result, size_t count) {
  while (count > 0) {
    CHECK((val[0] >= '0' && val[0] <= '9') || (val[0] >= 'a' && val[0] <= 'f'))
        << ": Invalid hex '" << val[0] << "'";
    CHECK((val[1] >= '0' && val[1] <= '9') || (val[1] >= 'a' && val[1] <= 'f'))
        << ": Invalid hex '" << val[1] << "'";

    uint8_t converted = 0;
    if (val[0] < 'a') {
      converted |= static_cast<uint8_t>(val[0] - '0') << 4;
    } else {
      converted |= (static_cast<uint8_t>(val[0] - 'a') + 0xa) << 4;
    }
    if (val[1] < 'a') {
      converted |= static_cast<uint8_t>(val[1] - '0');
    } else {
      converted |= (static_cast<uint8_t>(val[1] - 'a') + 0xa);
    }
    *result = converted;

    val += 2;
    ++result;
    --count;
  }
}

}  // namespace

namespace internal {
std::mt19937 FullySeededRandomGenerator() {
  // Total bits that the mt19937 has internally that we could plausibly
  // initialize with.
  // The internal state ends up being ~1200 bytes, which is significantly more
  // than the 128 bits we want for UUIDs, but since we should only need to
  // generate this randomness once, it should be fine.
  // If the performance cost ends up causing issues, then we can revisit the
  // need to *fully* seed the twister.
  constexpr size_t kInternalEntropy =
      std::mt19937::state_size * sizeof(std::mt19937::result_type);
  // Number, rounded up, of random values required.
  constexpr size_t kSeedsRequired =
      ((kInternalEntropy - 1) / sizeof(std::random_device::result_type)) + 1;
  std::random_device random_device;
// Older LLVM libstdc++'s just return 0 for the random device entropy.
#if !defined(__clang__) || (__clang_major__ > 13)
  CHECK_EQ(sizeof(std::random_device::result_type) * 8, random_device.entropy())
      << ": Does your random_device actually support generating entropy?";
#endif
  std::array<std::random_device::result_type, kSeedsRequired> random_data;
  std::generate(std::begin(random_data), std::end(random_data),
                std::ref(random_device));
  std::seed_seq seeds(std::begin(random_data), std::end(random_data));
  return std::mt19937(seeds);
}
}  // namespace internal

UUID UUID::Random() {
  // thread_local to guarantee safe use of the generator itself.
  thread_local std::mt19937 gen(internal::FullySeededRandomGenerator());

  std::uniform_int_distribution<> dis(0, 255);
  UUID result;
  for (size_t i = 0; i < kDataSize; ++i) {
    result.data_[i] = dis(gen);
  }

  // Mark the reserved bits in the data that this is a uuid4, a random UUID.
  result.data_[6] = (result.data_[6] & 0x0f) | 0x40;
  result.data_[8] = (result.data_[6] & 0x3f) | 0x80;

  return result;
}

std::string UUID::ToString() const {
  std::string out;
  out.resize(UUID::kStringSize);
  CopyTo(out.data());
  return out;
}

std::ostream &operator<<(std::ostream &os, const UUID &uuid) {
  return os << uuid.ToString();
}

flatbuffers::Offset<flatbuffers::String> UUID::PackString(
    flatbuffers::FlatBufferBuilder *fbb) const {
  std::array<char, kStringSize> data;
  CopyTo(data.data());

  return fbb->CreateString(data.data(), data.size());
}

flatbuffers::Offset<flatbuffers::Vector<uint8_t>> UUID::PackVector(
    flatbuffers::FlatBufferBuilder *fbb) const {
  return fbb->CreateVector(data_.data(), data_.size());
}

void UUID::CopyTo(char *result) const {
  ToHex(&data_[0], result, 4);
  result[8] = '-';
  ToHex(&data_[4], result + 9, 2);
  result[13] = '-';
  ToHex(&data_[6], result + 14, 2);
  result[18] = '-';
  ToHex(&data_[8], result + 19, 2);
  result[23] = '-';
  ToHex(&data_[10], result + 24, 6);
}

UUID UUID::FromString(const flatbuffers::String *str) {
  return FromString(str->string_view());
}

UUID UUID::FromVector(const flatbuffers::Vector<uint8_t> *data) {
  CHECK(data != nullptr);
  CHECK_EQ(data->size(), kDataSize);

  UUID result;
  std::memcpy(result.data_.data(), data->Data(), kDataSize);
  return result;
}

UUID UUID::FromSpan(absl::Span<const uint8_t> data) {
  CHECK_EQ(data.size(), kDataSize);

  UUID result;
  std::copy(data.begin(), data.end(), result.data_.begin());
  return result;
}

UUID UUID::FromString(std::string_view str) {
  CHECK_EQ(str.size(), kStringSize);

  UUID result;
  FromHex(str.data(), result.data_.data(), 4);
  CHECK(str.data()[8] == '-' && str.data()[13] == '-' &&
        str.data()[18] == '-' && str.data()[23] == '-')
      << ": Invalid uuid.";
  FromHex(str.data() + 9, result.data_.data() + 4, 2);
  FromHex(str.data() + 14, result.data_.data() + 6, 2);
  FromHex(str.data() + 19, result.data_.data() + 8, 2);
  FromHex(str.data() + 24, result.data_.data() + 10, 6);
  return result;
}

UUID UUID::BootUUID() {
  auto flag = absl::GetFlag(FLAGS_boot_uuid);
  if (!flag.empty()) {
    return UUID::FromString(flag);
  }

  int fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY);
  PCHECK(fd != -1);

  std::array<char, kStringSize> data;
  CHECK_EQ(static_cast<ssize_t>(kStringSize),
           read(fd, data.begin(), kStringSize));
  close(fd);

  return UUID::FromString(std::string_view(data.data(), data.size()));
}

}  // namespace aos
