/*
 Formatting library for C++

 Copyright (c) 2012 - 2016, Victor Zverovich
 All rights reserved.

 For the license information refer to format.h.
 */

#ifndef FMT_PRINTF_H_
#define FMT_PRINTF_H_

#include <algorithm>  // std::fill_n
#include <limits>     // std::numeric_limits

#include "fmt/ostream.h"

namespace fmt {
namespace internal {

// Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers.
template <bool IsSigned>
struct IntChecker {
  template <typename T>
  static bool fits_in_int(T value) {
    unsigned max = std::numeric_limits<int>::max();
    return value <= max;
  }
  static bool fits_in_int(bool) { return true; }
};

template <>
struct IntChecker<true> {
  template <typename T>
  static bool fits_in_int(T value) {
    return value >= std::numeric_limits<int>::min() &&
           value <= std::numeric_limits<int>::max();
  }
  static bool fits_in_int(int) { return true; }
};

class PrintfPrecisionHandler {
 public:
  template <typename T>
  typename std::enable_if<std::is_integral<T>::value, int>::type
      operator()(T value) {
    if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
      FMT_THROW(format_error("number is too big"));
    return static_cast<int>(value);
  }

  template <typename T>
  typename std::enable_if<!std::is_integral<T>::value, int>::type
      operator()(T) {
    FMT_THROW(format_error("precision is not integer"));
    return 0;
  }
};

// An argument visitor that returns true iff arg is a zero integer.
class IsZeroInt {
 public:
  template <typename T>
  typename std::enable_if<std::is_integral<T>::value, bool>::type
      operator()(T value) { return value == 0; }

  template <typename T>
  typename std::enable_if<!std::is_integral<T>::value, bool>::type
      operator()(T value) { return false; }
};

template <typename T, typename U>
struct is_same {
  enum { value = 0 };
};

template <typename T>
struct is_same<T, T> {
  enum { value = 1 };
};

template <typename T, typename Context>
class ArgConverter {
 private:
  typedef typename Context::char_type Char;

  basic_arg<Context> &arg_;
  typename Context::char_type type_;

 public:
  ArgConverter(basic_arg<Context> &arg, Char type)
    : arg_(arg), type_(type) {}

  void operator()(bool value) {
    if (type_ != 's')
      operator()<bool>(value);
  }

  template <typename U>
  typename std::enable_if<std::is_integral<U>::value>::type
      operator()(U value) {
    bool is_signed = type_ == 'd' || type_ == 'i';
    typedef typename internal::Conditional<
        is_same<T, void>::value, U, T>::type TargetType;
    typedef basic_format_context<Char> format_context;
    if (sizeof(TargetType) <= sizeof(int)) {
      // Extra casts are used to silence warnings.
      if (is_signed) {
        arg_ = internal::make_arg<Context>(
          static_cast<int>(static_cast<TargetType>(value)));
      } else {
        typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned;
        arg_ = internal::make_arg<Context>(
          static_cast<unsigned>(static_cast<Unsigned>(value)));
      }
    } else {
      if (is_signed) {
        // glibc's printf doesn't sign extend arguments of smaller types:
        //   std::printf("%lld", -42);  // prints "4294967254"
        // but we don't have to do the same because it's a UB.
        arg_ = internal::make_arg<Context>(static_cast<LongLong>(value));
      } else {
        arg_ = internal::make_arg<Context>(
          static_cast<typename internal::MakeUnsigned<U>::Type>(value));
      }
    }
  }

  template <typename U>
  typename std::enable_if<!std::is_integral<U>::value>::type
      operator()(U value) {
    // No coversion needed for non-integral types.
  }
};

// Converts an integer argument to T for printf, if T is an integral type.
// If T is void, the argument is converted to corresponding signed or unsigned
// type depending on the type specifier: 'd' and 'i' - signed, other -
// unsigned).
template <typename T, typename Context, typename Char>
void convert_arg(basic_arg<Context> &arg, Char type) {
  visit(ArgConverter<T, Context>(arg, type), arg);
}

// Converts an integer argument to char for printf.
template <typename Context>
class CharConverter {
 private:
  basic_arg<Context> &arg_;

  FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);

 public:
  explicit CharConverter(basic_arg<Context> &arg) : arg_(arg) {}

  template <typename T>
  typename std::enable_if<std::is_integral<T>::value>::type
      operator()(T value) {
    arg_ = internal::make_arg<Context>(static_cast<char>(value));
  }

  template <typename T>
  typename std::enable_if<!std::is_integral<T>::value>::type operator()(T) {
    // No coversion needed for non-integral types.
  }
};

// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
template <typename Char>
class PrintfWidthHandler {
 private:
  typedef basic_format_specs<Char> format_specs;

  format_specs &spec_;

  FMT_DISALLOW_COPY_AND_ASSIGN(PrintfWidthHandler);

 public:
  explicit PrintfWidthHandler(format_specs &spec) : spec_(spec) {}

  template <typename T>
  typename std::enable_if<std::is_integral<T>::value, unsigned>::type
      operator()(T value) {
    typedef typename internal::IntTraits<T>::MainType UnsignedType;
    UnsignedType width = static_cast<UnsignedType>(value);
    if (internal::is_negative(value)) {
      spec_.align_ = ALIGN_LEFT;
      width = 0 - width;
    }
    unsigned int_max = std::numeric_limits<int>::max();
    if (width > int_max)
      FMT_THROW(format_error("number is too big"));
    return static_cast<unsigned>(width);
  }

  template <typename T>
  typename std::enable_if<!std::is_integral<T>::value, unsigned>::type
      operator()(T value) {
    FMT_THROW(format_error("width is not integer"));
    return 0;
  }
};
}  // namespace internal

/**
  \rst
  The ``printf`` argument formatter.
  \endrst
 */
template <typename Char>
class PrintfArgFormatter : public internal::ArgFormatterBase<Char> {
 private:
  void write_null_pointer() {
    this->spec().type_ = 0;
    this->write("(nil)");
  }

  typedef internal::ArgFormatterBase<Char> Base;

 public:
  typedef typename Base::format_specs format_specs;

  /**
    \rst
    Constructs an argument formatter object.
    *writer* is a reference to the output writer and *spec* contains format
    specifier information for standard argument types.
    \endrst
   */
  PrintfArgFormatter(basic_writer<Char> &writer, format_specs &spec)
  : internal::ArgFormatterBase<Char>(writer, spec) {}

  using Base::operator();

  /** Formats an argument of type ``bool``. */
  void operator()(bool value) {
    format_specs &fmt_spec = this->spec();
    if (fmt_spec.type_ != 's')
      return (*this)(value ? 1 : 0);
    fmt_spec.type_ = 0;
    this->write(value);
  }

  /** Formats a character. */
  void operator()(Char value) {
    const format_specs &fmt_spec = this->spec();
    basic_writer<Char> &w = this->writer();
    if (fmt_spec.type_ && fmt_spec.type_ != 'c')
      w.write_int(value, fmt_spec);
    typedef typename basic_writer<Char>::CharPtr CharPtr;
    CharPtr out = CharPtr();
    if (fmt_spec.width_ > 1) {
      Char fill = ' ';
      out = w.grow_buffer(fmt_spec.width_);
      if (fmt_spec.align_ != ALIGN_LEFT) {
        std::fill_n(out, fmt_spec.width_ - 1, fill);
        out += fmt_spec.width_ - 1;
      } else {
        std::fill_n(out + 1, fmt_spec.width_ - 1, fill);
      }
    } else {
      out = w.grow_buffer(1);
    }
    *out = static_cast<Char>(value);
  }

  /** Formats a null-terminated C string. */
  void operator()(const char *value) {
    if (value)
      Base::operator()(value);
    else if (this->spec().type_ == 'p')
      write_null_pointer();
    else
      this->write("(null)");
  }

  /** Formats a pointer. */
  void operator()(const void *value) {
    if (value)
      return Base::operator()(value);
    this->spec().type_ = 0;
    write_null_pointer();
  }

  /** Formats an argument of a custom (user-defined) type. */
  void operator()(internal::CustomValue<Char> c) {
    const Char format_str[] = {'}', '\0'};
    auto args = basic_args<basic_format_context<Char>>();
    basic_format_context<Char> ctx(format_str, args);
    c.format(this->writer(), c.value, &ctx);
  }
};

/** This template formats data and writes the output to a writer. */
template <typename Char,
          typename ArgFormatter = PrintfArgFormatter<Char> >
class printf_context :
  private internal::format_context_base<
    Char, printf_context<Char, ArgFormatter>> {
 public:
  /** The character type for the output. */
  typedef Char char_type;

 private:
  typedef internal::format_context_base<Char, printf_context> Base;
  typedef typename Base::format_arg format_arg;
  typedef basic_format_specs<Char> format_specs;

  void parse_flags(format_specs &spec, const Char *&s);

  // Returns the argument with specified index or, if arg_index is equal
  // to the maximum unsigned value, the next argument.
  format_arg get_arg(
      const Char *s,
      unsigned arg_index = (std::numeric_limits<unsigned>::max)());

  // Parses argument index, flags and width and returns the argument index.
  unsigned parse_header(const Char *&s, format_specs &spec);

 public:
  /**
   \rst
   Constructs a ``printf_context`` object. References to the arguments and
   the writer are stored in the context object so make sure they have
   appropriate lifetimes.
   \endrst
   */
  explicit printf_context(BasicCStringRef<Char> format_str,
                          basic_args<printf_context> args)
    : Base(format_str.c_str(), args) {}

  /** Formats stored arguments and writes the output to the writer. */
  FMT_API void format(basic_writer<Char> &writer);
};

template <typename Char, typename AF>
void printf_context<Char, AF>::parse_flags(format_specs &spec, const Char *&s) {
  for (;;) {
    switch (*s++) {
      case '-':
        spec.align_ = ALIGN_LEFT;
        break;
      case '+':
        spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
        break;
      case '0':
        spec.fill_ = '0';
        break;
      case ' ':
        spec.flags_ |= SIGN_FLAG;
        break;
      case '#':
        spec.flags_ |= HASH_FLAG;
        break;
      default:
        --s;
        return;
    }
  }
}

template <typename Char, typename AF>
typename printf_context<Char, AF>::format_arg printf_context<Char, AF>::get_arg(
    const Char *s, unsigned arg_index) {
  (void)s;
  const char *error = 0;
  format_arg arg = arg_index == std::numeric_limits<unsigned>::max() ?
    this->next_arg(error) : Base::get_arg(arg_index - 1, error);
  if (error)
    FMT_THROW(format_error(!*s ? "invalid format string" : error));
  return arg;
}

template <typename Char, typename AF>
unsigned printf_context<Char, AF>::parse_header(
  const Char *&s, format_specs &spec) {
  unsigned arg_index = std::numeric_limits<unsigned>::max();
  Char c = *s;
  if (c >= '0' && c <= '9') {
    // Parse an argument index (if followed by '$') or a width possibly
    // preceded with '0' flag(s).
    unsigned value = internal::parse_nonnegative_int(s);
    if (*s == '$') {  // value is an argument index
      ++s;
      arg_index = value;
    } else {
      if (c == '0')
        spec.fill_ = '0';
      if (value != 0) {
        // Nonzero value means that we parsed width and don't need to
        // parse it or flags again, so return now.
        spec.width_ = value;
        return arg_index;
      }
    }
  }
  parse_flags(spec, s);
  // Parse width.
  if (*s >= '0' && *s <= '9') {
    spec.width_ = internal::parse_nonnegative_int(s);
  } else if (*s == '*') {
    ++s;
    spec.width_ = visit(internal::PrintfWidthHandler<Char>(spec), get_arg(s));
  }
  return arg_index;
}

template <typename Char, typename AF>
void printf_context<Char, AF>::format(basic_writer<Char> &writer) {
  const Char *start = this->ptr();
  const Char *s = start;
  while (*s) {
    Char c = *s++;
    if (c != '%') continue;
    if (*s == c) {
      internal::write(writer, start, s);
      start = ++s;
      continue;
    }
    internal::write(writer, start, s - 1);

    format_specs spec;
    spec.align_ = ALIGN_RIGHT;

    // Parse argument index, flags and width.
    unsigned arg_index = parse_header(s, spec);

    // Parse precision.
    if (*s == '.') {
      ++s;
      if ('0' <= *s && *s <= '9') {
        spec.precision_ = static_cast<int>(internal::parse_nonnegative_int(s));
      } else if (*s == '*') {
        ++s;
        spec.precision_ = visit(internal::PrintfPrecisionHandler(), get_arg(s));
      }
    }

    format_arg arg = get_arg(s, arg_index);
    if (spec.flag(HASH_FLAG) && visit(internal::IsZeroInt(), arg))
      spec.flags_ &= ~internal::to_unsigned<int>(HASH_FLAG);
    if (spec.fill_ == '0') {
      if (arg.is_numeric())
        spec.align_ = ALIGN_NUMERIC;
      else
        spec.fill_ = ' ';  // Ignore '0' flag for non-numeric types.
    }

    // Parse length and convert the argument to the required type.
    using internal::convert_arg;
    switch (*s++) {
    case 'h':
      if (*s == 'h')
        convert_arg<signed char>(arg, *++s);
      else
        convert_arg<short>(arg, *s);
      break;
    case 'l':
      if (*s == 'l')
        convert_arg<fmt::LongLong>(arg, *++s);
      else
        convert_arg<long>(arg, *s);
      break;
    case 'j':
      convert_arg<intmax_t>(arg, *s);
      break;
    case 'z':
      convert_arg<std::size_t>(arg, *s);
      break;
    case 't':
      convert_arg<std::ptrdiff_t>(arg, *s);
      break;
    case 'L':
      // printf produces garbage when 'L' is omitted for long double, no
      // need to do the same.
      break;
    default:
      --s;
      convert_arg<void>(arg, *s);
    }

    // Parse type.
    if (!*s)
      FMT_THROW(format_error("invalid format string"));
    spec.type_ = static_cast<char>(*s++);
    if (arg.is_integral()) {
      // Normalize type.
      switch (spec.type_) {
      case 'i': case 'u':
        spec.type_ = 'd';
        break;
      case 'c':
        // TODO: handle wchar_t
        visit(internal::CharConverter<printf_context<Char, AF>>(arg), arg);
        break;
      }
    }

    start = s;

    // Format argument.
    visit(AF(writer, spec), arg);
  }
  internal::write(writer, start, s);
}

// Formats a value.
template <typename Char, typename T>
void format_value(basic_writer<Char> &w, const T &value,
                  printf_context<Char>& ctx) {
  internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
  w.write(internal::format_value(buffer, value));
}

template <typename Char>
void printf(basic_writer<Char> &w, BasicCStringRef<Char> format,
            basic_args<printf_context<Char>> args) {
  printf_context<Char>(format, args).format(w);
}

typedef basic_args<printf_context<char>> printf_args;

inline std::string vsprintf(CStringRef format, printf_args args) {
  MemoryWriter w;
  printf(w, format, args);
  return w.str();
}

/**
  \rst
  Formats arguments and returns the result as a string.

  **Example**::

    std::string message = fmt::sprintf("The answer is %d", 42);
  \endrst
*/
template <typename... Args>
inline std::string sprintf(CStringRef format_str, const Args & ... args) {
  return vsprintf(format_str, make_xformat_args<printf_context<char>>(args...));
}

inline std::wstring vsprintf(
    WCStringRef format, basic_args<printf_context<wchar_t>> args) {
  WMemoryWriter w;
  printf(w, format, args);
  return w.str();
}

template <typename... Args>
inline std::wstring sprintf(WCStringRef format_str, const Args & ... args) {
  auto vargs = make_xformat_args<printf_context<wchar_t>>(args...);
  return vsprintf(format_str, vargs);
}

FMT_API int vfprintf(std::FILE *f, CStringRef format, printf_args args);

/**
  \rst
  Prints formatted data to the file *f*.

  **Example**::

    fmt::fprintf(stderr, "Don't %s!", "panic");
  \endrst
 */
template <typename... Args>
inline int fprintf(std::FILE *f, CStringRef format_str, const Args & ... args) {
  auto vargs = make_xformat_args<printf_context<char>>(args...);
  return vfprintf(f, format_str, vargs);
}

inline int vprintf(CStringRef format, printf_args args) {
  return vfprintf(stdout, format, args);
}

/**
  \rst
  Prints formatted data to ``stdout``.

  **Example**::

    fmt::printf("Elapsed time: %.2f seconds", 1.23);
  \endrst
 */
template <typename... Args>
inline int printf(CStringRef format_str, const Args & ... args) {
  return vprintf(format_str, make_xformat_args<printf_context<char>>(args...));
}

inline int vfprintf(std::ostream &os, CStringRef format_str, printf_args args) {
  MemoryWriter w;
  printf(w, format_str, args);
  internal::write(os, w);
  return static_cast<int>(w.size());
}

/**
  \rst
  Prints formatted data to the stream *os*.

  **Example**::

    fprintf(cerr, "Don't %s!", "panic");
  \endrst
 */
template <typename... Args>
inline int fprintf(std::ostream &os, CStringRef format_str,
                   const Args & ... args) {
  auto vargs = make_xformat_args<printf_context<char>>(args...);
  return vfprintf(os, format_str, vargs);
}
}  // namespace fmt

#endif  // FMT_PRINTF_H_
