// Copyright 2018 The Abseil 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.

#ifndef ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_
#define ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_

#include <algorithm>
#include <cstdint>
#include <iostream>
#include <string>

#include "absl/base/config.h"
#include "absl/strings/ascii.h"
#include "absl/strings/internal/charconv_parse.h"
#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace strings_internal {

// The largest power that 5 that can be raised to, and still fit in a uint32_t.
constexpr int kMaxSmallPowerOfFive = 13;
// The largest power that 10 that can be raised to, and still fit in a uint32_t.
constexpr int kMaxSmallPowerOfTen = 9;

ABSL_DLL extern const uint32_t
    kFiveToNth[kMaxSmallPowerOfFive + 1];
ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1];

// Large, fixed-width unsigned integer.
//
// Exact rounding for decimal-to-binary floating point conversion requires very
// large integer math, but a design goal of absl::from_chars is to avoid
// allocating memory.  The integer precision needed for decimal-to-binary
// conversions is large but bounded, so a huge fixed-width integer class
// suffices.
//
// This is an intentionally limited big integer class.  Only needed operations
// are implemented.  All storage lives in an array data member, and all
// arithmetic is done in-place, to avoid requiring separate storage for operand
// and result.
//
// This is an internal class.  Some methods live in the .cc file, and are
// instantiated only for the values of max_words we need.
template <int max_words>
class BigUnsigned {
 public:
  static_assert(max_words == 4 || max_words == 84,
                "unsupported max_words value");

  BigUnsigned() : size_(0), words_{} {}
  explicit constexpr BigUnsigned(uint64_t v)
      : size_((v >> 32) ? 2 : v ? 1 : 0),
        words_{static_cast<uint32_t>(v & 0xffffffffu),
               static_cast<uint32_t>(v >> 32)} {}

  // Constructs a BigUnsigned from the given string_view containing a decimal
  // value.  If the input string is not a decimal integer, constructs a 0
  // instead.
  explicit BigUnsigned(absl::string_view sv) : size_(0), words_{} {
    // Check for valid input, returning a 0 otherwise.  This is reasonable
    // behavior only because this constructor is for unit tests.
    if (std::find_if_not(sv.begin(), sv.end(), ascii_isdigit) != sv.end() ||
        sv.empty()) {
      return;
    }
    int exponent_adjust =
        ReadDigits(sv.data(), sv.data() + sv.size(), Digits10() + 1);
    if (exponent_adjust > 0) {
      MultiplyByTenToTheNth(exponent_adjust);
    }
  }

  // Loads the mantissa value of a previously-parsed float.
  //
  // Returns the associated decimal exponent.  The value of the parsed float is
  // exactly *this * 10**exponent.
  int ReadFloatMantissa(const ParsedFloat& fp, int significant_digits);

  // Returns the number of decimal digits of precision this type provides.  All
  // numbers with this many decimal digits or fewer are representable by this
  // type.
  //
  // Analagous to std::numeric_limits<BigUnsigned>::digits10.
  static constexpr int Digits10() {
    // 9975007/1035508 is very slightly less than log10(2**32).
    return static_cast<uint64_t>(max_words) * 9975007 / 1035508;
  }

  // Shifts left by the given number of bits.
  void ShiftLeft(int count) {
    if (count > 0) {
      const int word_shift = count / 32;
      if (word_shift >= max_words) {
        SetToZero();
        return;
      }
      size_ = (std::min)(size_ + word_shift, max_words);
      count %= 32;
      if (count == 0) {
        std::copy_backward(words_, words_ + size_ - word_shift, words_ + size_);
      } else {
        for (int i = (std::min)(size_, max_words - 1); i > word_shift; --i) {
          words_[i] = (words_[i - word_shift] << count) |
                      (words_[i - word_shift - 1] >> (32 - count));
        }
        words_[word_shift] = words_[0] << count;
        // Grow size_ if necessary.
        if (size_ < max_words && words_[size_]) {
          ++size_;
        }
      }
      std::fill(words_, words_ + word_shift, 0u);
    }
  }


  // Multiplies by v in-place.
  void MultiplyBy(uint32_t v) {
    if (size_ == 0 || v == 1) {
      return;
    }
    if (v == 0) {
      SetToZero();
      return;
    }
    const uint64_t factor = v;
    uint64_t window = 0;
    for (int i = 0; i < size_; ++i) {
      window += factor * words_[i];
      words_[i] = window & 0xffffffff;
      window >>= 32;
    }
    // If carry bits remain and there's space for them, grow size_.
    if (window && size_ < max_words) {
      words_[size_] = window & 0xffffffff;
      ++size_;
    }
  }

  void MultiplyBy(uint64_t v) {
    uint32_t words[2];
    words[0] = static_cast<uint32_t>(v);
    words[1] = static_cast<uint32_t>(v >> 32);
    if (words[1] == 0) {
      MultiplyBy(words[0]);
    } else {
      MultiplyBy(2, words);
    }
  }

  // Multiplies in place by 5 to the power of n.  n must be non-negative.
  void MultiplyByFiveToTheNth(int n) {
    while (n >= kMaxSmallPowerOfFive) {
      MultiplyBy(kFiveToNth[kMaxSmallPowerOfFive]);
      n -= kMaxSmallPowerOfFive;
    }
    if (n > 0) {
      MultiplyBy(kFiveToNth[n]);
    }
  }

  // Multiplies in place by 10 to the power of n.  n must be non-negative.
  void MultiplyByTenToTheNth(int n) {
    if (n > kMaxSmallPowerOfTen) {
      // For large n, raise to a power of 5, then shift left by the same amount.
      // (10**n == 5**n * 2**n.)  This requires fewer multiplications overall.
      MultiplyByFiveToTheNth(n);
      ShiftLeft(n);
    } else if (n > 0) {
      // We can do this more quickly for very small N by using a single
      // multiplication.
      MultiplyBy(kTenToNth[n]);
    }
  }

  // Returns the value of 5**n, for non-negative n.  This implementation uses
  // a lookup table, and is faster then seeding a BigUnsigned with 1 and calling
  // MultiplyByFiveToTheNth().
  static BigUnsigned FiveToTheNth(int n);

  // Multiplies by another BigUnsigned, in-place.
  template <int M>
  void MultiplyBy(const BigUnsigned<M>& other) {
    MultiplyBy(other.size(), other.words());
  }

  void SetToZero() {
    std::fill(words_, words_ + size_, 0u);
    size_ = 0;
  }

  // Returns the value of the nth word of this BigUnsigned.  This is
  // range-checked, and returns 0 on out-of-bounds accesses.
  uint32_t GetWord(int index) const {
    if (index < 0 || index >= size_) {
      return 0;
    }
    return words_[index];
  }

  // Returns this integer as a decimal string.  This is not used in the decimal-
  // to-binary conversion; it is intended to aid in testing.
  std::string ToString() const;

  int size() const { return size_; }
  const uint32_t* words() const { return words_; }

 private:
  // Reads the number between [begin, end), possibly containing a decimal point,
  // into this BigUnsigned.
  //
  // Callers are required to ensure [begin, end) contains a valid number, with
  // one or more decimal digits and at most one decimal point.  This routine
  // will behave unpredictably if these preconditions are not met.
  //
  // Only the first `significant_digits` digits are read.  Digits beyond this
  // limit are "sticky": If the final significant digit is 0 or 5, and if any
  // dropped digit is nonzero, then that final significant digit is adjusted up
  // to 1 or 6.  This adjustment allows for precise rounding.
  //
  // Returns `exponent_adjustment`, a power-of-ten exponent adjustment to
  // account for the decimal point and for dropped significant digits.  After
  // this function returns,
  //   actual_value_of_parsed_string ~= *this * 10**exponent_adjustment.
  int ReadDigits(const char* begin, const char* end, int significant_digits);

  // Performs a step of big integer multiplication.  This computes the full
  // (64-bit-wide) values that should be added at the given index (step), and
  // adds to that location in-place.
  //
  // Because our math all occurs in place, we must multiply starting from the
  // highest word working downward.  (This is a bit more expensive due to the
  // extra carries involved.)
  //
  // This must be called in steps, for each word to be calculated, starting from
  // the high end and working down to 0.  The first value of `step` should be
  //   `std::min(original_size + other.size_ - 2, max_words - 1)`.
  // The reason for this expression is that multiplying the i'th word from one
  // multiplicand and the j'th word of another multiplicand creates a
  // two-word-wide value to be stored at the (i+j)'th element.  The highest
  // word indices we will access are `original_size - 1` from this object, and
  // `other.size_ - 1` from our operand.  Therefore,
  // `original_size + other.size_ - 2` is the first step we should calculate,
  // but limited on an upper bound by max_words.

  // Working from high-to-low ensures that we do not overwrite the portions of
  // the initial value of *this which are still needed for later steps.
  //
  // Once called with step == 0, *this contains the result of the
  // multiplication.
  //
  // `original_size` is the size_ of *this before the first call to
  // MultiplyStep().  `other_words` and `other_size` are the contents of our
  // operand.  `step` is the step to perform, as described above.
  void MultiplyStep(int original_size, const uint32_t* other_words,
                    int other_size, int step);

  void MultiplyBy(int other_size, const uint32_t* other_words) {
    const int original_size = size_;
    const int first_step =
        (std::min)(original_size + other_size - 2, max_words - 1);
    for (int step = first_step; step >= 0; --step) {
      MultiplyStep(original_size, other_words, other_size, step);
    }
  }

  // Adds a 32-bit value to the index'th word, with carry.
  void AddWithCarry(int index, uint32_t value) {
    if (value) {
      while (index < max_words && value > 0) {
        words_[index] += value;
        // carry if we overflowed in this word:
        if (value > words_[index]) {
          value = 1;
          ++index;
        } else {
          value = 0;
        }
      }
      size_ = (std::min)(max_words, (std::max)(index + 1, size_));
    }
  }

  void AddWithCarry(int index, uint64_t value) {
    if (value && index < max_words) {
      uint32_t high = value >> 32;
      uint32_t low = value & 0xffffffff;
      words_[index] += low;
      if (words_[index] < low) {
        ++high;
        if (high == 0) {
          // Carry from the low word caused our high word to overflow.
          // Short circuit here to do the right thing.
          AddWithCarry(index + 2, static_cast<uint32_t>(1));
          return;
        }
      }
      if (high > 0) {
        AddWithCarry(index + 1, high);
      } else {
        // Normally 32-bit AddWithCarry() sets size_, but since we don't call
        // it when `high` is 0, do it ourselves here.
        size_ = (std::min)(max_words, (std::max)(index + 1, size_));
      }
    }
  }

  // Divide this in place by a constant divisor.  Returns the remainder of the
  // division.
  template <uint32_t divisor>
  uint32_t DivMod() {
    uint64_t accumulator = 0;
    for (int i = size_ - 1; i >= 0; --i) {
      accumulator <<= 32;
      accumulator += words_[i];
      // accumulator / divisor will never overflow an int32_t in this loop
      words_[i] = static_cast<uint32_t>(accumulator / divisor);
      accumulator = accumulator % divisor;
    }
    while (size_ > 0 && words_[size_ - 1] == 0) {
      --size_;
    }
    return static_cast<uint32_t>(accumulator);
  }

  // The number of elements in words_ that may carry significant values.
  // All elements beyond this point are 0.
  //
  // When size_ is 0, this BigUnsigned stores the value 0.
  // When size_ is nonzero, is *not* guaranteed that words_[size_ - 1] is
  // nonzero.  This can occur due to overflow truncation.
  // In particular, x.size_ != y.size_ does *not* imply x != y.
  int size_;
  uint32_t words_[max_words];
};

// Compares two big integer instances.
//
// Returns -1 if lhs < rhs, 0 if lhs == rhs, and 1 if lhs > rhs.
template <int N, int M>
int Compare(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
  int limit = (std::max)(lhs.size(), rhs.size());
  for (int i = limit - 1; i >= 0; --i) {
    const uint32_t lhs_word = lhs.GetWord(i);
    const uint32_t rhs_word = rhs.GetWord(i);
    if (lhs_word < rhs_word) {
      return -1;
    } else if (lhs_word > rhs_word) {
      return 1;
    }
  }
  return 0;
}

template <int N, int M>
bool operator==(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
  int limit = (std::max)(lhs.size(), rhs.size());
  for (int i = 0; i < limit; ++i) {
    if (lhs.GetWord(i) != rhs.GetWord(i)) {
      return false;
    }
  }
  return true;
}

template <int N, int M>
bool operator!=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
  return !(lhs == rhs);
}

template <int N, int M>
bool operator<(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
  return Compare(lhs, rhs) == -1;
}

template <int N, int M>
bool operator>(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
  return rhs < lhs;
}
template <int N, int M>
bool operator<=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
  return !(rhs < lhs);
}
template <int N, int M>
bool operator>=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) {
  return !(lhs < rhs);
}

// Output operator for BigUnsigned, for testing purposes only.
template <int N>
std::ostream& operator<<(std::ostream& os, const BigUnsigned<N>& num) {
  return os << num.ToString();
}

// Explicit instantiation declarations for the sizes of BigUnsigned that we
// are using.
//
// For now, the choices of 4 and 84 are arbitrary; 4 is a small value that is
// still bigger than an int128, and 84 is a large value we will want to use
// in the from_chars implementation.
//
// Comments justifying the use of 84 belong in the from_chars implementation,
// and will be added in a follow-up CL.
extern template class BigUnsigned<4>;
extern template class BigUnsigned<84>;

}  // namespace strings_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_
