// 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 <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/errors.h>

#include <iomanip>
#include <iostream>
#include <memory>

#include <fbl/alloc_checker.h>
#include <fbl/string.h>

// See note in //zircon/third_party/ulib/boringssl/BUILD.gn
#define BORINGSSL_NO_CXX
#include <utility>

#include <openssl/mem.h>
#include <openssl/sha.h>

#include "src/lib/digest/digest.h"

namespace digest {

// The previously opaque crypto implementation context.
struct Digest::Context {
  SHA256_CTX impl;
};

Digest::Digest() : bytes_{0} {}

Digest::Digest(const uint8_t (&bytes)[sizeof(bytes_)]) { *this = bytes; }

Digest::Digest(Digest&& other) { *this = std::move(other); }

Digest::~Digest() {}

Digest& Digest::operator=(const uint8_t (&bytes)[sizeof(bytes_)]) {
  ctx_.reset();
  memcpy(bytes_, bytes, sizeof(bytes_));
  return *this;
}

Digest& Digest::operator=(Digest&& other) {
  ctx_ = std::move(other.ctx_);
  memcpy(bytes_, other.bytes_, sizeof(bytes_));
  memset(other.bytes_, 0, sizeof(other.bytes_));
  return *this;
}

Digest::Digest(const Digest& other) {
  ZX_DEBUG_ASSERT(!other.ctx_);  // Can only copy finalized digests.
  memcpy(bytes_, other.bytes_, sizeof(bytes_));
}

Digest& Digest::operator=(const Digest& other) {
  ZX_DEBUG_ASSERT(!other.ctx_);  // Can only copy finalized digests.
  memcpy(bytes_, other.bytes_, sizeof(bytes_));
  return *this;
}

void Digest::Init() {
  ctx_.reset(new Context());
  SHA256_Init(&ctx_->impl);
}

void Digest::Update(const void* buf, size_t len) {
  ZX_DEBUG_ASSERT(ctx_);
  ZX_DEBUG_ASSERT(len <= INT_MAX);
  SHA256_Update(&ctx_->impl, buf, len);
}

const uint8_t* Digest::Final() {
  ZX_DEBUG_ASSERT(ctx_);
  SHA256_Final(bytes_, &ctx_->impl);
  ctx_.reset();
  return bytes_;
}

const uint8_t* Digest::Hash(const void* buf, size_t len) {
  Init();
  Update(buf, len);
  return Final();
}

zx_status_t Digest::Parse(const char* hex, size_t len) {
  if (len != sizeof(bytes_) * 2) {
    return ZX_ERR_INVALID_ARGS;
  }
  size_t i = 0;
  for (size_t j = 0; j < sizeof(bytes_) * 2; ++j) {
    int c = toupper(hex[j]);
    if (!isxdigit(c)) {
      return ZX_ERR_INVALID_ARGS;
    }
    c = c < 'A' ? c - '0' : c - '7';  // '7' = 'A' - 10
    if (j % 2 == 0) {
      bytes_[i] = static_cast<uint8_t>(c << 4);
    } else {
      bytes_[i++] |= static_cast<uint8_t>(c);
    }
  }
  return ZX_OK;
}

fbl::String Digest::ToString() const {
  char hex[kSha256HexLength + 1];
  char* p = hex;
  for (size_t i = 0; i < sizeof(bytes_); ++i) {
    sprintf(p, "%02x", bytes_[i]);
    p += 2;
  }
  return fbl::String(hex);
}

void Digest::CopyTo(uint8_t* out, size_t len) const {
  ZX_DEBUG_ASSERT(len >= sizeof(bytes_));
  CopyTruncatedTo(out, len);
}

void Digest::CopyTruncatedTo(uint8_t* out, size_t len) const {
  if (len == 0) {
    return;
  } else if (len <= sizeof(bytes_)) {
    memcpy(out, bytes_, len);
  } else {
    memcpy(out, bytes_, sizeof(bytes_));
    out += sizeof(bytes_);
    len -= sizeof(bytes_);
    memset(out, 0, len);
  }
}

bool Digest::Equals(const uint8_t* rhs, size_t len) const {
  return rhs && len == sizeof(bytes_) && CRYPTO_memcmp(bytes_, rhs, sizeof(bytes_)) == 0;
}

std::ostream& operator<<(std::ostream& stream, const Digest& digest) {
  std::ios::fmtflags f(stream.flags());
  for (uint8_t byte : digest.bytes_) {
    stream << std::setfill('0') << std::hex << std::setw(2) << int{byte};
  }
  stream.flags(f);
  return stream;
}

}  // namespace digest
