// Copyright 2018 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 "src/developer/debug/zxdb/common/string_util.h"

#include <inttypes.h>

#include <iomanip>
#include <sstream>

namespace zxdb {

namespace {

std::string DoToHexString(uint64_t value, int digits, bool include_prefix) {
  std::ostringstream out;
  if (include_prefix)
    out << "0x";

  if (digits)
    out << std::setw(digits) << std::setfill('0');

  out << std::hex << value;
  return out.str();
}

}  // namespace

// Cast signed numbers to their unsigned variant before converting to 64-bit to avoid sign
// extension.
std::string to_hex_string(int8_t i, int digits, bool include_prefix) {
  return DoToHexString(static_cast<uint8_t>(i), digits, include_prefix);
}
std::string to_hex_string(uint8_t i, int digits, bool include_prefix) {
  return DoToHexString(i, digits, include_prefix);
}
std::string to_hex_string(int16_t i, int digits, bool include_prefix) {
  return DoToHexString(static_cast<uint16_t>(i), digits, include_prefix);
}
std::string to_hex_string(uint16_t i, int digits, bool include_prefix) {
  return DoToHexString(i, digits, include_prefix);
}
std::string to_hex_string(int32_t i, int digits, bool include_prefix) {
  return DoToHexString(static_cast<uint32_t>(i), digits, include_prefix);
}
std::string to_hex_string(uint32_t i, int digits, bool include_prefix) {
  return DoToHexString(i, digits, include_prefix);
}
std::string to_hex_string(int64_t i, int digits, bool include_prefix) {
  return DoToHexString(static_cast<uint64_t>(i), digits, include_prefix);
}
std::string to_hex_string(uint64_t i, int digits, bool include_prefix) {
  return DoToHexString(i, digits, include_prefix);
}

// Format the 128-bit numbers as two 64-bit ones.
std::string to_hex_string(int128_t i, int digits, bool include_prefix) {
  return to_hex_string(static_cast<uint128_t>(i), digits, include_prefix);
}
std::string to_hex_string(uint128_t i, int digits, bool include_prefix) {
  if (i <= std::numeric_limits<uint64_t>::max())
    return to_hex_string(static_cast<uint64_t>(i), digits, include_prefix);

  // Compute the padding to apply to just the high 64 bits. The low 64 bits will always have 16.
  int high_digits = 0;
  if (digits > 16)
    high_digits = digits - 16;

  std::string result = to_hex_string(static_cast<uint64_t>(i >> 64), high_digits, include_prefix);
  result += to_hex_string(static_cast<uint64_t>(i), 16, false);
  return result;
}

template <typename T>
std::string to_bin_string(T value, int digits, bool include_prefix, char byte_separator) {
  std::ostringstream out;
  if (include_prefix)
    out << "0b";

  // When no padding is requested, always output at least one digit.
  if (digits == 0)
    digits = 1;

  int high_bit = sizeof(T) * 8 - 1;              // Largest bit of the input type (0-based).
  bool written_digit = false;                    // Set when we've written any digit.
  int cur_bit = std::max(digits - 1, high_bit);  // 0-based bit index (counting from low bit).

  // Computes whether a byte separator is needed at cur_bit.
  auto needs_separator = [&]() {
    return written_digit &&         // Don't do a leading separator.
           byte_separator &&        // Separator requested.
           (cur_bit + 1) % 8 == 0;  // Byte boundary.
  };

  // Left 0-padding for padding beyond the range of the input type.
  while (cur_bit > high_bit) {
    if (needs_separator())
      out << byte_separator;
    out << '0';

    written_digit = true;
    cur_bit--;
  }

  while (cur_bit >= 0) {
    if (needs_separator())
      out << byte_separator;

    bool bit_value = value & (static_cast<T>(1) << cur_bit);
    if (bit_value || written_digit || (cur_bit + 1) <= digits) {
      out << (bit_value ? '1' : '0');
      written_digit = true;
    }

    cur_bit--;
  }

  return out.str();
}

template std::string to_bin_string<int8_t>(int8_t i, int digits, bool include_prefix,
                                           char byte_separator);
template std::string to_bin_string<uint8_t>(uint8_t i, int digits, bool include_prefix,
                                            char byte_separator);
template std::string to_bin_string<int16_t>(int16_t i, int digits, bool include_prefix,
                                            char byte_separator);
template std::string to_bin_string<uint16_t>(uint16_t i, int digits, bool include_prefix,
                                             char byte_separator);
template std::string to_bin_string<int32_t>(int32_t i, int digits, bool include_prefix,
                                            char byte_separator);
template std::string to_bin_string<uint32_t>(uint32_t i, int digits, bool include_prefix,
                                             char byte_separator);
template std::string to_bin_string<int64_t>(int64_t i, int digits, bool include_prefix,
                                            char byte_separator);
template std::string to_bin_string<uint64_t>(uint64_t i, int digits, bool include_prefix,
                                             char byte_separator);
template std::string to_bin_string<int128_t>(int128_t i, int digits, bool include_prefix,
                                             char byte_separator);
template std::string to_bin_string<uint128_t>(uint128_t i, int digits, bool include_prefix,
                                              char byte_separator);

}  // namespace zxdb
