#include "yaml-cpp/fptostring.h"
#include "contrib/dragonbox.h"

#include <array>
#include <cassert>
#include <cmath>
#include <limits>
#include <sstream>
#include <tuple>

namespace YAML {
namespace detail {
namespace fp_formatting {

/**
 * Converts a integer into its ASCII digits.
 *
 * @param begin/end - a buffer, must be at least 20bytes long.
 * @param value     - input value.
 * @param width     - minimum number of digits, fill with '0' to the left. Must be equal or smaller than the buffer size.
 * @return          - number of digits filled into the buffer (or -1 if preconditions are not meet)
 *
 * Example:
 * std::array<char, 20> buffer;
 * auto ct = ConvertToChars(buffer.begin(), buffer.end(), 23, 3);
 * assert(ct = 3);
 * assert(buffer[0] == '0');
 * assert(buffer[1] == '2');
 * assert(buffer[2] == '3');
 */
int ConvertToChars(char* begin, char* end, size_t value, int width=1) {
  // precondition of this function (will trigger in debug build)
  assert(width >= 1);
  assert(end >= begin);       // end must be after begin
  assert(end-begin >= width); // Buffer must be large enough
  assert(end-begin >= 20);    // 2^64 has 20digits, so at least 20 digits must be available

  // defensive programming, abort if precondition are not met (will trigger in release build)
  if (width < 1) {
    return -1;
  }
  if (end < begin) {
    return -1;
  }
  if (end-begin < width) {
    return -1;
  }
  if (end-begin < 20) {
    return -1;
  }


  // count number of digits, and fill digits array accordingly
  int digits_ct{};
  while (value > 0) {
    char c = value % 10 + '0';
    value = value / 10;
    digits_ct += 1;
    *(end-digits_ct) = c;
  }
  while(digits_ct < width) {
    assert(digits_ct < 64);
    digits_ct += 1;
    *(end-digits_ct) = '0';
  }
  // move data to the front of the array
  std::memmove(begin, end-digits_ct, digits_ct);
  return digits_ct;
}

/**
 * Converts a float or double to a string.
 *
 * converts a value 'v' to a string. Uses dragonbox for formatting.
 */
template <typename T>
std::string FpToString(T v, int precision = 0) {
  // hard coded constant, at which exponent should switch to a scientific notation
  int const lowerExponentThreshold = -5;
  int const upperExponentThreshold =  (precision==0)?6:precision;
  if (precision == 0) {
    precision = 6;
  }

  // dragonbox/to_decimal does not handle value 0, inf, NaN
  if (v == 0 || std::isinf(v) || std::isnan(v)) {
    std::stringstream ss;
    ss.imbue(std::locale::classic());
    ss << v;
    return ss.str();
  }

  auto r = jkj::dragonbox::to_decimal(v);

  auto digits  = std::array<char, 20>{}; // max digits of size_t is 20.
  auto digits_ct = ConvertToChars(digits.data(), digits.data() + digits.size(), r.significand);

  // defensive programming, ConvertToChars arguments are invalid
  if (digits_ct == -1) {
    std::stringstream ss;
    ss.imbue(std::locale::classic());
    ss << v;
    return ss.str();
  }

  // check if requested precision is lower than
  // required digits for exact representation
  if (digits_ct > precision) {
    auto diff = digits_ct - precision;
    r.exponent += diff;
    digits_ct = precision;

    // round numbers if required
    if (digits[digits_ct] >= '5') {
      int i{digits_ct-1};
      digits[i] += 1;
      while (digits[i] == '9'+1) {
        digits_ct -= 1;
        r.exponent += 1;
        if (i > 0) {
          digits[i-1] += 1;
          i -= 1;
        } else {
          digits_ct = 1;
          digits[0] = '1';
          break;
        }
      }
    }
  }

  // Case 1 - scientific notation: max digits of size_t plus sign, a dot and 2 letters for 'e+' or 'e-' and 4 letters for the exponent
  // Case 2 - default notation: require up to precision number of digits and one for a potential sign
  std::array<char, 28> output_buffer;
  auto output_ptr = &output_buffer[0];

  // Helper variable that in Case 2 counts the overflowing number of zeros that do not fit into the buffer.
  int overflow_zeros = 0;

  // print '-' symbol for negative numbers
  if (r.is_negative) {
    *(output_ptr++) = '-';
  }

  // exponent if only a single non-zero digit is before the decimal point
  int const exponent = r.exponent + digits_ct - 1;

  // case 1: scientific notation
  if (exponent >= upperExponentThreshold || exponent <= lowerExponentThreshold) {
    // print first digit
    *(output_ptr++) = digits[0];

    // print digits after decimal point
    if (digits_ct > 1) {
      *(output_ptr++) = '.';
      // print significant numbers after decimal point
      for (int i{1}; i < digits_ct; ++i) {
         *(output_ptr++) = digits[i];
      }
    }
    *(output_ptr++) = 'e';
    *(output_ptr++) = (exponent>=0)?'+':'-';
    auto exp_digits = std::array<char, 20>{};
    auto exp_digits_ct = ConvertToChars(exp_digits.data(), exp_digits.data() + exp_digits.size(), std::abs(exponent), /*.precision=*/ 2);

    // defensive programming, ConvertToChars arguments are invalid
    if (exp_digits_ct == -1) {
      std::stringstream ss;
      ss.imbue(std::locale::classic());
      ss << v;
      return ss.str();
    }

    for (int i{0}; i < exp_digits_ct; ++i) {
      *(output_ptr++) = exp_digits[i];
    }

  // case 2: default notation
  } else {
    auto const digits_end = digits.begin() + digits_ct;
    auto digits_iter = digits.begin();

    // print digits before point
    int const before_decimal_digits = digits_ct + r.exponent;
    if (before_decimal_digits > 0) {
      // print non-zero digits before point
      for (int i{0}; i < std::min(before_decimal_digits, digits_ct); ++i) {
        *(output_ptr++) = *(digits_iter++);
      }

      // number of digits that have to be zero
      int const zero_digits_ct = before_decimal_digits - digits_ct;

      // space left in the output_buffer (-1 because we need it for null-termination)
      int const buffer_empty_space = output_buffer.data() + output_buffer.size() - output_ptr - 1;

      // print all zeros not fitting into the buffer at the end of the function
      overflow_zeros = std::max(0, zero_digits_ct - buffer_empty_space);

      // print trailing zeros before point
      for (int i{0}; i < zero_digits_ct - overflow_zeros; ++i) {
        *(output_ptr++) = '0';
      }

    // print 0 before point if none where printed before
    } else {
      *(output_ptr++) = '0';
    }

    if (digits_iter != digits_end) {
      *(output_ptr++) = '.';
      // print 0 after decimal point, to fill until first digits
      int const after_decimal_zeros = -digits_ct - r.exponent;
      for (int i{0}; i < after_decimal_zeros; ++i) {
         *(output_ptr++) = '0';
      }

      // print significant numbers after decimal point
      for (;digits_iter < digits_end; ++digits_iter) {
         *(output_ptr++) = *digits_iter;
      }
    }
  }
  *output_ptr = '\0';
  auto ret_value = std::string{&output_buffer[0], output_ptr};
  ret_value.resize(ret_value.size() + overflow_zeros, '0');
  return ret_value;
}

}
}

std::string FpToString(float v, size_t precision) {
  return detail::fp_formatting::FpToString(v, precision);
}

std::string FpToString(double v, size_t precision) {
  return detail::fp_formatting::FpToString(v, precision);
}

/**
 * dragonbox only works for floats/doubles not long double
 */
std::string FpToString(long double v, size_t precision) {
  std::stringstream ss;
  ss.imbue(std::locale::classic());
  if (precision == 0) {
     precision = std::numeric_limits<long double>::max_digits10;
  }
  ss.precision(precision);
  ss << v;
  return ss.str();
}

}
