// Copyright 2019 The Pigweed Authors
//
// 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 "pw_string/type_to_string.h"

#include <cmath>
#include <cstddef>
#include <cstring>
#include <limits>

namespace pw::string {
namespace {

// Powers of 10 (except 0) as an array. This table is fairly large (160 B), but
// avoids having to recalculate these values for each DecimalDigitCount call.
constexpr std::array<uint64_t, 20> kPowersOf10{
    0ull,
    10ull,                    // 10^1
    100ull,                   // 10^2
    1000ull,                  // 10^3
    10000ull,                 // 10^4
    100000ull,                // 10^5
    1000000ull,               // 10^6
    10000000ull,              // 10^7
    100000000ull,             // 10^8
    1000000000ull,            // 10^9
    10000000000ull,           // 10^10
    100000000000ull,          // 10^11
    1000000000000ull,         // 10^12
    10000000000000ull,        // 10^13
    100000000000000ull,       // 10^14
    1000000000000000ull,      // 10^15
    10000000000000000ull,     // 10^16
    100000000000000000ull,    // 10^17
    1000000000000000000ull,   // 10^18
    10000000000000000000ull,  // 10^19
};

StatusWithSize HandleExhaustedBuffer(const span<char>& buffer) {
  if (!buffer.empty()) {
    buffer[0] = '\0';
  }
  return StatusWithSize::RESOURCE_EXHAUSTED;
}

}  // namespace

uint_fast8_t DecimalDigitCount(uint64_t integer) {
  // This fancy piece of code takes the log base 2, then approximates the
  // change-of-base formula by multiplying by 1233 / 4096.
  // TODO(hepler): Replace __builtin_clzll with std::countl_zeros in C++20.
  const uint_fast8_t log_10 = (64 - __builtin_clzll(integer | 1)) * 1233 >> 12;

  // Adjust the estimated log base 10 by comparing against the power of 10.
  return log_10 + (integer < kPowersOf10[log_10] ? 0u : 1u);
}

// std::to_chars is available for integers in recent versions of GCC. I looked
// into switching to std::to_chars instead of this implementation. std::to_chars
// increased binary size by 160 B on an -Os build (even after removing
// DecimalDigitCount and its table). I didn't measure performance, but I don't
// think std::to_chars will be faster, so I kept this implementation for now.
template <>
StatusWithSize IntToString(uint64_t value, const span<char>& buffer) {
  constexpr uint32_t base = 10;
  constexpr uint32_t max_uint32_base_power = 1'000'000'000;
  constexpr uint_fast8_t max_uint32_base_power_exponent = 9;

  const uint_fast8_t total_digits = DecimalDigitCount(value);

  if (total_digits >= buffer.size()) {
    return HandleExhaustedBuffer(buffer);
  }

  buffer[total_digits] = '\0';

  uint_fast8_t remaining = total_digits;
  while (remaining > 0u) {
    uint32_t lower_digits;     // the value of the lower digits to write
    uint_fast8_t digit_count;  // the number of lower digits to write

    // 64-bit division is slow on 32-bit platforms, so print large numbers in
    // 32-bit chunks to minimize the number of 64-bit divisions.
    if (value <= std::numeric_limits<uint32_t>::max()) {
      lower_digits = value;
      digit_count = remaining;
    } else {
      lower_digits = value % max_uint32_base_power;
      digit_count = max_uint32_base_power_exponent;
      value /= max_uint32_base_power;
    }

    // Write the specified number of digits, with leading 0s.
    for (uint_fast8_t i = 0; i < digit_count; ++i) {
      buffer[--remaining] = lower_digits % base + '0';
      lower_digits /= base;
    }
  }
  return StatusWithSize(total_digits);
}

StatusWithSize IntToHexString(uint64_t value, const span<char>& buffer) {
  const uint_fast8_t digits = HexDigitCount(value);

  if (digits >= buffer.size()) {
    return HandleExhaustedBuffer(buffer);
  }

  for (int i = digits - 1; i >= 0; --i) {
    buffer[i] = "0123456789abcdef"[value & 0xF];
    value >>= 4;
  }

  buffer[digits] = '\0';
  return StatusWithSize(digits);
}

template <>
StatusWithSize IntToString(int64_t value, const span<char>& buffer) {
  if (value >= 0) {
    return IntToString<uint64_t>(value, buffer);
  }

  // Write as an unsigned number, but leave room for the leading minus sign.
  auto result = IntToString<uint64_t>(
      std::abs(value), buffer.empty() ? buffer : buffer.subspan(1));

  if (result.ok()) {
    buffer[0] = '-';
    return StatusWithSize(result.size() + 1);
  }

  return HandleExhaustedBuffer(buffer);
}

// TODO(hepler): Look into using the float overload of std::to_chars when it is
//     available.
StatusWithSize FloatAsIntToString(float value, const span<char>& buffer) {
  // If it's finite and fits in an int64_t, print it as a rounded integer.
  if (std::isfinite(value) &&
      std::abs(value) <
          static_cast<float>(std::numeric_limits<int64_t>::max())) {
    return IntToString<int64_t>(std::round(value), buffer);
  }

  // Otherwise, print inf or NaN, if they fit.
  if (const size_t written = 3 + std::signbit(value); written < buffer.size()) {
    char* out = buffer.data();
    if (std::signbit(value)) {
      *out++ = '-';
    }
    std::memcpy(out, std::isnan(value) ? "NaN" : "inf", sizeof("NaN"));
    return StatusWithSize(written);
  }

  return HandleExhaustedBuffer(buffer);
}

StatusWithSize BoolToString(bool value, const span<char>& buffer) {
  return CopyEntireString(value ? "true" : "false", buffer);
}

StatusWithSize PointerToString(const void* pointer, const span<char>& buffer) {
  if (pointer == nullptr) {
    return CopyEntireString(kNullPointerString, buffer);
  }
  return IntToHexString(reinterpret_cast<uintptr_t>(pointer), buffer);
}

StatusWithSize CopyString(const std::string_view& value,
                          const span<char>& buffer) {
  if (buffer.empty()) {
    return StatusWithSize::RESOURCE_EXHAUSTED;
  }

  const size_t copied = value.copy(buffer.data(), buffer.size() - 1);
  buffer[copied] = '\0';

  return StatusWithSize(
      copied == value.size() ? Status::OK : Status::RESOURCE_EXHAUSTED, copied);
}

StatusWithSize CopyEntireString(const std::string_view& value,
                                const span<char>& buffer) {
  if (value.size() >= buffer.size()) {
    return HandleExhaustedBuffer(buffer);
  }

  std::memcpy(buffer.data(), value.data(), value.size());
  buffer[value.size()] = '\0';
  return StatusWithSize(value.size());
}

}  // namespace pw::string
