//
// POSIX spec:
//   http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
//
#include "absl/strings/internal/str_format/arg.h"

#include <cassert>
#include <cerrno>
#include <cstdlib>
#include <string>
#include <type_traits>

#include "absl/base/port.h"
#include "absl/strings/internal/str_format/float_conversion.h"

namespace absl {
inline namespace lts_2018_12_18 {
namespace str_format_internal {
namespace {

const char kDigit[2][32] = { "0123456789abcdef", "0123456789ABCDEF" };

// Reduce *capacity by s.size(), clipped to a 0 minimum.
void ReducePadding(string_view s, size_t *capacity) {
  *capacity = Excess(s.size(), *capacity);
}

// Reduce *capacity by n, clipped to a 0 minimum.
void ReducePadding(size_t n, size_t *capacity) {
  *capacity = Excess(n, *capacity);
}

template <typename T>
struct MakeUnsigned : std::make_unsigned<T> {};
template <>
struct MakeUnsigned<absl::uint128> {
  using type = absl::uint128;
};

template <typename T>
struct IsSigned : std::is_signed<T> {};
template <>
struct IsSigned<absl::uint128> : std::false_type {};

class ConvertedIntInfo {
 public:
  template <typename T>
  ConvertedIntInfo(T v, ConversionChar conv) {
    using Unsigned = typename MakeUnsigned<T>::type;
    auto u = static_cast<Unsigned>(v);
    if (IsNeg(v)) {
      is_neg_ = true;
      u = Unsigned{} - u;
    } else {
      is_neg_ = false;
    }
    UnsignedToStringRight(u, conv);
  }

  string_view digits() const {
    return {end() - size_, static_cast<size_t>(size_)};
  }
  bool is_neg() const { return is_neg_; }

 private:
  template <typename T, bool IsSigned>
  struct IsNegImpl {
    static bool Eval(T v) { return v < 0; }
  };
  template <typename T>
  struct IsNegImpl<T, false> {
    static bool Eval(T) {
      return false;
    }
  };

  template <typename T>
  bool IsNeg(T v) {
    return IsNegImpl<T, IsSigned<T>::value>::Eval(v);
  }

  template <typename T>
  void UnsignedToStringRight(T u, ConversionChar conv) {
    char *p = end();
    switch (conv.radix()) {
      default:
      case 10:
        for (; u; u /= 10)
          *--p = static_cast<char>('0' + static_cast<size_t>(u % 10));
        break;
      case 8:
        for (; u; u /= 8)
          *--p = static_cast<char>('0' + static_cast<size_t>(u % 8));
        break;
      case 16: {
        const char *digits = kDigit[conv.upper() ? 1 : 0];
        for (; u; u /= 16) *--p = digits[static_cast<size_t>(u % 16)];
        break;
      }
    }
    size_ = static_cast<int>(end() - p);
  }

  const char *end() const { return storage_ + sizeof(storage_); }
  char *end() { return storage_ + sizeof(storage_); }

  bool is_neg_;
  int size_;
  // Max size: 128 bit value as octal -> 43 digits
  char storage_[128 / 3 + 1];
};

// Note: 'o' conversions do not have a base indicator, it's just that
// the '#' flag is specified to modify the precision for 'o' conversions.
string_view BaseIndicator(const ConvertedIntInfo &info,
                          const ConversionSpec conv) {
  bool alt = conv.flags().alt;
  int radix = conv.conv().radix();
  if (conv.conv().id() == ConversionChar::p)
    alt = true;  // always show 0x for %p.
  // From the POSIX description of '#' flag:
  //   "For x or X conversion specifiers, a non-zero result shall have
  //   0x (or 0X) prefixed to it."
  if (alt && radix == 16 && !info.digits().empty()) {
    if (conv.conv().upper()) return "0X";
    return "0x";
  }
  return {};
}

string_view SignColumn(bool neg, const ConversionSpec conv) {
  if (conv.conv().is_signed()) {
    if (neg) return "-";
    if (conv.flags().show_pos) return "+";
    if (conv.flags().sign_col) return " ";
  }
  return {};
}

bool ConvertCharImpl(unsigned char v, const ConversionSpec conv,
                     FormatSinkImpl *sink) {
  size_t fill = 0;
  if (conv.width() >= 0) fill = conv.width();
  ReducePadding(1, &fill);
  if (!conv.flags().left) sink->Append(fill, ' ');
  sink->Append(1, v);
  if (conv.flags().left) sink->Append(fill, ' ');
  return true;
}

bool ConvertIntImplInner(const ConvertedIntInfo &info,
                         const ConversionSpec conv, FormatSinkImpl *sink) {
  // Print as a sequence of Substrings:
  //   [left_spaces][sign][base_indicator][zeroes][formatted][right_spaces]
  size_t fill = 0;
  if (conv.width() >= 0) fill = conv.width();

  string_view formatted = info.digits();
  ReducePadding(formatted, &fill);

  string_view sign = SignColumn(info.is_neg(), conv);
  ReducePadding(sign, &fill);

  string_view base_indicator = BaseIndicator(info, conv);
  ReducePadding(base_indicator, &fill);

  int precision = conv.precision();
  bool precision_specified = precision >= 0;
  if (!precision_specified)
    precision = 1;

  if (conv.flags().alt && conv.conv().id() == ConversionChar::o) {
    // From POSIX description of the '#' (alt) flag:
    //   "For o conversion, it increases the precision (if necessary) to
    //   force the first digit of the result to be zero."
    if (formatted.empty() || *formatted.begin() != '0') {
      int needed = static_cast<int>(formatted.size()) + 1;
      precision = std::max(precision, needed);
    }
  }

  size_t num_zeroes = Excess(formatted.size(), precision);
  ReducePadding(num_zeroes, &fill);

  size_t num_left_spaces = !conv.flags().left ? fill : 0;
  size_t num_right_spaces = conv.flags().left ? fill : 0;

  // From POSIX description of the '0' (zero) flag:
  //   "For d, i, o, u, x, and X conversion specifiers, if a precision
  //   is specified, the '0' flag is ignored."
  if (!precision_specified && conv.flags().zero) {
    num_zeroes += num_left_spaces;
    num_left_spaces = 0;
  }

  sink->Append(num_left_spaces, ' ');
  sink->Append(sign);
  sink->Append(base_indicator);
  sink->Append(num_zeroes, '0');
  sink->Append(formatted);
  sink->Append(num_right_spaces, ' ');
  return true;
}

template <typename T>
bool ConvertIntImplInner(T v, const ConversionSpec conv, FormatSinkImpl *sink) {
  ConvertedIntInfo info(v, conv.conv());
  if (conv.flags().basic && conv.conv().id() != ConversionChar::p) {
    if (info.is_neg()) sink->Append(1, '-');
    if (info.digits().empty()) {
      sink->Append(1, '0');
    } else {
      sink->Append(info.digits());
    }
    return true;
  }
  return ConvertIntImplInner(info, conv, sink);
}

template <typename T>
bool ConvertIntArg(T v, const ConversionSpec conv, FormatSinkImpl *sink) {
  if (conv.conv().is_float()) {
    return FormatConvertImpl(static_cast<double>(v), conv, sink).value;
  }
  if (conv.conv().id() == ConversionChar::c)
    return ConvertCharImpl(static_cast<unsigned char>(v), conv, sink);
  if (!conv.conv().is_integral())
    return false;
  if (!conv.conv().is_signed() && IsSigned<T>::value) {
    using U = typename MakeUnsigned<T>::type;
    return FormatConvertImpl(static_cast<U>(v), conv, sink).value;
  }
  return ConvertIntImplInner(v, conv, sink);
}

template <typename T>
bool ConvertFloatArg(T v, const ConversionSpec conv, FormatSinkImpl *sink) {
  return conv.conv().is_float() && ConvertFloatImpl(v, conv, sink);
}

inline bool ConvertStringArg(string_view v, const ConversionSpec conv,
                             FormatSinkImpl *sink) {
  if (conv.conv().id() != ConversionChar::s)
    return false;
  if (conv.flags().basic) {
    sink->Append(v);
    return true;
  }
  return sink->PutPaddedString(v, conv.width(), conv.precision(),
                               conv.flags().left);
}

}  // namespace

// ==================== Strings ====================
ConvertResult<Conv::s> FormatConvertImpl(const std::string &v,
                                         const ConversionSpec conv,
                                         FormatSinkImpl *sink) {
  return {ConvertStringArg(v, conv, sink)};
}

ConvertResult<Conv::s> FormatConvertImpl(string_view v,
                                         const ConversionSpec conv,
                                         FormatSinkImpl *sink) {
  return {ConvertStringArg(v, conv, sink)};
}

ConvertResult<Conv::s | Conv::p> FormatConvertImpl(const char *v,
                                                   const ConversionSpec conv,
                                                   FormatSinkImpl *sink) {
  if (conv.conv().id() == ConversionChar::p)
    return {FormatConvertImpl(VoidPtr(v), conv, sink).value};
  size_t len;
  if (v == nullptr) {
    len = 0;
  } else if (conv.precision() < 0) {
    len = std::strlen(v);
  } else {
    // If precision is set, we look for the null terminator on the valid range.
    len = std::find(v, v + conv.precision(), '\0') - v;
  }
  return {ConvertStringArg(string_view(v, len), conv, sink)};
}

// ==================== Raw pointers ====================
ConvertResult<Conv::p> FormatConvertImpl(VoidPtr v, const ConversionSpec conv,
                                         FormatSinkImpl *sink) {
  if (conv.conv().id() != ConversionChar::p)
    return {false};
  if (!v.value) {
    sink->Append("(nil)");
    return {true};
  }
  return {ConvertIntImplInner(v.value, conv, sink)};
}

// ==================== Floats ====================
FloatingConvertResult FormatConvertImpl(float v, const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertFloatArg(v, conv, sink)};
}
FloatingConvertResult FormatConvertImpl(double v, const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertFloatArg(v, conv, sink)};
}
FloatingConvertResult FormatConvertImpl(long double v,
                                        const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertFloatArg(v, conv, sink)};
}

// ==================== Chars ====================
IntegralConvertResult FormatConvertImpl(char v, const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}
IntegralConvertResult FormatConvertImpl(signed char v,
                                        const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}
IntegralConvertResult FormatConvertImpl(unsigned char v,
                                        const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}

// ==================== Ints ====================
IntegralConvertResult FormatConvertImpl(short v,  // NOLINT
                                        const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}
IntegralConvertResult FormatConvertImpl(unsigned short v,  // NOLINT
                                        const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}
IntegralConvertResult FormatConvertImpl(int v, const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}
IntegralConvertResult FormatConvertImpl(unsigned v, const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}
IntegralConvertResult FormatConvertImpl(long v,  // NOLINT
                                        const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}
IntegralConvertResult FormatConvertImpl(unsigned long v,  // NOLINT
                                        const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}
IntegralConvertResult FormatConvertImpl(long long v,  // NOLINT
                                        const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}
IntegralConvertResult FormatConvertImpl(unsigned long long v,  // NOLINT
                                        const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}
IntegralConvertResult FormatConvertImpl(absl::uint128 v,
                                        const ConversionSpec conv,
                                        FormatSinkImpl *sink) {
  return {ConvertIntArg(v, conv, sink)};
}

ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_();


}  // namespace str_format_internal

}  // inline namespace lts_2018_12_18
}  // namespace absl
