// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "uuid/uuid.h"

#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>

#include <cstdint>
#include <string>

#include "absl/base/no_destructor.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/random/distributions.h"
#include "absl/random/random.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "riegeli/endian/endian_reading.h"
#include "riegeli/endian/endian_writing.h"

namespace credentio {

namespace {
class UuidGeneratorImpl : public UuidGenerator {
 public:
  // Generates a V4 UUID as documented in
  // https://tools.ietf.org/html/rfc4122#section-4.4
  Uuid Generate() const override {
    absl::BitGen gen;
    const auto lo = absl::Uniform<uint64_t>(gen);
    const auto hi = absl::Uniform<uint64_t>(gen);
    return Uuid((lo & 0x0fffffffffffffffUL) | 0x4000000000000000UL,
                (hi & 0xffffffffffffbfffUL) | 0x0000000000008000UL);
  };
};
}  // namespace

////////////////////////////////////////////////////////////////////////
// Uuid and related helpers

// Canonical Uids.
const Uuid Uuid::kInvalid;

// We reserve the node 00:00:00:00:00:00, time [0, 999] for invalid
// Uuids (constants)
const Uuid Uuid::kValidMin(0, ValidMinLo());
const Uuid Uuid::kValidMax(~0ULL, ~0ULL);

std::string Uuid::ToString() const {
  if (*this == kInvalid) return std::string(kInvalidRepr);

  auto to_hex = [](uint64_t v, int num_chars, char* out) {
    static constexpr char hex_char[] = {'0', '1', '2', '3', '4', '5', '6', '7',
                                        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    for (int i = num_chars - 1; i >= 0; --i) {
      *out++ = hex_char[(v >> (i * 4)) & 0xf];
    }
  };
  uint32_t time_low = low64() & 0xffffffff;
  uint32_t time_mid = (low64() >> 32) & 0xffff;
  uint32_t time_high = (low64() >> 48) & 0xffff;
  uint32_t sequence = high64() & 0xffff;
  uint64_t node = (high64() >> 16) & 0xffffffffffffULL;
  char buf[36];
  char* ptr = buf;
  to_hex(time_low, 8, ptr);
  ptr += 8;
  *ptr++ = '-';
  to_hex(time_mid, 4, ptr);
  ptr += 4;
  *ptr++ = '-';
  to_hex(time_high, 4, ptr);
  ptr += 4;
  *ptr++ = '-';
  to_hex(sequence, 4, ptr);
  ptr += 4;
  *ptr++ = '-';
  to_hex(node, 12, ptr);
  return std::string(buf, 36);
}

absl::StatusOr<Uuid> Uuid::FromString(absl::string_view s) {
  Uuid uuid;
  if (!ParseFromString(s, &uuid)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Syntax error: string '", s, "' is not a Uuid"));
  }
  return uuid;
}

std::string Uuid::ToProtoBytes() const {
  std::string s;
  ToProtoBytes(&s);
  return s;
}

// The UUid byte format is a mixed-endian format specified by RFC 4122.
void Uuid::ToProtoBytes(std::string* s) const {
  // Special case for kInvalidUID, which is represented as the empty string.
  if (*this == kInvalid) {
    s->assign("");
    return;
  }

  char bytes[16];
  uint32_t time_low = low64() & 0xffffffff;
  uint16_t time_mid = (low64() >> 32) & 0xffff;
  uint16_t time_hi_and_version = (low64() >> 48) & 0xffff;
  uint16_t clock_seq = high64() & 0xffff;
  uint16_t node_low = (high64() >> 16) & 0xffff;
  uint32_t node_hi = (high64() >> 32) & 0xffffffff;

  riegeli::WriteBigEndian<uint32_t>(time_low, &bytes[0]);
  riegeli::WriteBigEndian<uint16_t>(time_mid, &bytes[4]);
  riegeli::WriteBigEndian<uint16_t>(time_hi_and_version, &bytes[6]);
  riegeli::WriteBigEndian<uint16_t>(clock_seq, &bytes[8]);
  riegeli::WriteBigEndian<uint32_t>(node_hi, &bytes[10]);
  riegeli::WriteBigEndian<uint16_t>(node_low, &bytes[14]);
  s->assign(bytes, 16);
}

absl::StatusOr<Uuid> Uuid::FromProtoBytes(absl::string_view bytes) {
  if (bytes.empty()) {
    return Uuid(kInvalid);
  } else if (bytes.size() == 16) {
    const char* data = bytes.data();
    uint64_t time_low = riegeli::ReadBigEndian<uint32_t>(&data[0]);
    uint64_t time_mid = riegeli::ReadBigEndian<uint16_t>(&data[4]);
    uint64_t time_hi_and_version = riegeli::ReadBigEndian<uint16_t>(&data[6]);
    uint64_t clock_seq = riegeli::ReadBigEndian<uint16_t>(&data[8]);
    uint64_t node_hi = riegeli::ReadBigEndian<uint32_t>(&data[10]);
    uint64_t node_low = riegeli::ReadBigEndian<uint16_t>(&data[14]);
    uint64_t low64 = (time_hi_and_version << 48) | (time_mid << 32) | time_low;
    uint64_t high64 = (node_hi << 32) | (node_low << 16) | clock_seq;
    return Uuid(high64, low64);
  }
  return ::absl::InvalidArgumentError("Syntax error: bytes are not a Uuid");
}

bool Uuid::IsValid() const { return kValidMin <= *this && *this <= kValidMax; }

bool Uuid::IsMagic() const { return high_ == 0 && low_ < ValidMinLo(); }

const UuidGenerator& UuidGenerator::Default() {
  static const absl::NoDestructor<UuidGeneratorImpl> kDefaultUuidGenerator;
  return *kDefaultUuidGenerator;
}

}  // namespace credentio
