/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2014 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmUuid.h"

#include <string.h>

#include "cm_sha2.h"
#include <cmsys/MD5.h>

cmUuid::cmUuid()
{
  Groups.push_back(4);
  Groups.push_back(2);
  Groups.push_back(2);
  Groups.push_back(2);
  Groups.push_back(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);

  cmsysMD5_s* md5 = cmsysMD5_New();
  cmsysMD5_Initialize(md5);
  cmsysMD5_Append(md5, &hashInput[0], int(hashInput.size()));

  unsigned char digest[16] = { 0 };
  cmsysMD5_Finalize(md5, digest);

  cmsysMD5_Delete(md5);

  return this->FromDigest(digest, 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);

  SHA_CTX* sha = new SHA_CTX;
  SHA1_Init(sha);
  SHA1_Update(sha, &hashInput[0], hashInput.size());

  unsigned char digest[SHA1_DIGEST_LENGTH] = { 0 };
  SHA1_Final(digest, sha);

  delete sha;

  return this->FromDigest(digest, 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
{
  typedef unsigned char byte_t;

  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 < this->Groups.size(); ++i) {
    if (i != 0 && input[index++] != '-') {
      return false;
    }
    size_t digits = this->Groups[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 < this->Groups.size(); ++i) {
    if (i != 0) {
      output += '-';
    }

    size_t bytes = this->Groups[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 = c + result;
  }

  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;
  } else if (input >= 'a' && input <= 'f') {
    output = char(input - 'a' + 0xA);
    return true;
  } else if (input >= 'A' && input <= 'F') {
    output = char(input - 'A' + 0xA);
    return true;
  } else {
    return false;
  }
}
