/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmUuid.h"

#include <array>
#include <cstring>

#include "cmCryptoHash.h"

static const std::array<int, 5> kUuidGroups = { { 4, 2, 2, 2, 6 } };

std::string cmUuid::FromMd5(std::vector<unsigned char> const& uuidNamespace,
                            std::string const& name) const
{
  std::vector<unsigned char> hashInput;
  this->CreateHashInput(uuidNamespace, name, hashInput);

  cmCryptoHash md5(cmCryptoHash::AlgoMD5);
  md5.Initialize();
  md5.Append(&hashInput[0], hashInput.size());
  std::vector<unsigned char> digest = md5.Finalize();

  return this->FromDigest(&digest[0], 3);
}

std::string cmUuid::FromSha1(std::vector<unsigned char> const& uuidNamespace,
                             std::string const& name) const
{
  std::vector<unsigned char> hashInput;
  this->CreateHashInput(uuidNamespace, name, hashInput);

  cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
  sha1.Initialize();
  sha1.Append(&hashInput[0], hashInput.size());
  std::vector<unsigned char> digest = sha1.Finalize();

  return this->FromDigest(&digest[0], 5);
}

void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
                             std::string const& name,
                             std::vector<unsigned char>& output) const
{
  output = uuidNamespace;

  if (!name.empty()) {
    output.resize(output.size() + name.size());

    memcpy(&output[0] + uuidNamespace.size(), name.c_str(), name.size());
  }
}

std::string cmUuid::FromDigest(const unsigned char* digest,
                               unsigned char version) const
{
  using byte_t = unsigned char;

  byte_t uuid[16] = { 0 };
  memcpy(uuid, digest, 16);

  uuid[6] &= 0xF;
  uuid[6] |= byte_t(version << 4);

  uuid[8] &= 0x3F;
  uuid[8] |= 0x80;

  return this->BinaryToString(uuid);
}

bool cmUuid::StringToBinary(std::string const& input,
                            std::vector<unsigned char>& output) const
{
  output.clear();
  output.reserve(16);

  if (input.length() != 36) {
    return false;
  }
  size_t index = 0;
  for (size_t i = 0; i < kUuidGroups.size(); ++i) {
    if (i != 0 && input[index++] != '-') {
      return false;
    }
    size_t digits = kUuidGroups[i] * 2;
    if (!StringToBinaryImpl(input.substr(index, digits), output)) {
      return false;
    }

    index += digits;
  }

  return true;
}

std::string cmUuid::BinaryToString(const unsigned char* input) const
{
  std::string output;

  size_t inputIndex = 0;
  for (size_t i = 0; i < kUuidGroups.size(); ++i) {
    if (i != 0) {
      output += '-';
    }

    size_t bytes = kUuidGroups[i];
    for (size_t j = 0; j < bytes; ++j) {
      unsigned char byte = input[inputIndex++];
      output += this->ByteToHex(byte);
    }
  }

  return output;
}

std::string cmUuid::ByteToHex(unsigned char byte) const
{
  std::string result("  ");
  for (int i = 0; i < 2; ++i) {
    unsigned char rest = byte % 16;
    byte /= 16;
    char c = (rest < 0xA) ? char('0' + rest) : char('a' + (rest - 0xA));
    result.at(1 - i) = c;
  }

  return result;
}

bool cmUuid::StringToBinaryImpl(std::string const& input,
                                std::vector<unsigned char>& output) const
{
  if (input.size() % 2) {
    return false;
  }

  for (size_t i = 0; i < input.size(); i += 2) {
    char c1 = 0;
    if (!IntFromHexDigit(input[i], c1)) {
      return false;
    }

    char c2 = 0;
    if (!IntFromHexDigit(input[i + 1], c2)) {
      return false;
    }

    output.push_back(char(c1 << 4 | c2));
  }

  return true;
}

bool cmUuid::IntFromHexDigit(char input, char& output) const
{
  if (input >= '0' && input <= '9') {
    output = char(input - '0');
    return true;
  }
  if (input >= 'a' && input <= 'f') {
    output = char(input - 'a' + 0xA);
    return true;
  }
  if (input >= 'A' && input <= 'F') {
    output = char(input - 'A' + 0xA);
    return true;
  }
  return false;
}
