//
// Copyright 2017 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
//
//      http://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_STR_FORMAT_EXTENSION_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_

#include <limits.h>
#include <cstring>
#include <ostream>

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

class Cord;

namespace absl {

namespace str_format_internal {

class FormatRawSinkImpl {
 public:
  // Implicitly convert from any type that provides the hook function as
  // described above.
  template <typename T, decltype(str_format_internal::InvokeFlush(
                            std::declval<T*>(), string_view()))* = nullptr>
  FormatRawSinkImpl(T* raw)  // NOLINT
      : sink_(raw), write_(&FormatRawSinkImpl::Flush<T>) {}

  void Write(string_view s) { write_(sink_, s); }

  template <typename T>
  static FormatRawSinkImpl Extract(T s) {
    return s.sink_;
  }

 private:
  template <typename T>
  static void Flush(void* r, string_view s) {
    str_format_internal::InvokeFlush(static_cast<T*>(r), s);
  }

  void* sink_;
  void (*write_)(void*, string_view);
};

// An abstraction to which conversions write their std::string data.
class FormatSinkImpl {
 public:
  explicit FormatSinkImpl(FormatRawSinkImpl raw) : raw_(raw) {}

  ~FormatSinkImpl() { Flush(); }

  void Flush() {
    raw_.Write(string_view(buf_, pos_ - buf_));
    pos_ = buf_;
  }

  void Append(size_t n, char c) {
    if (n == 0) return;
    size_ += n;
    auto raw_append = [&](size_t count) {
      memset(pos_, c, count);
      pos_ += count;
    };
    while (n > Avail()) {
      n -= Avail();
      if (Avail() > 0) {
        raw_append(Avail());
      }
      Flush();
    }
    raw_append(n);
  }

  void Append(string_view v) {
    size_t n = v.size();
    if (n == 0) return;
    size_ += n;
    if (n >= Avail()) {
      Flush();
      raw_.Write(v);
      return;
    }
    memcpy(pos_, v.data(), n);
    pos_ += n;
  }

  size_t size() const { return size_; }

  // Put 'v' to 'sink' with specified width, precision, and left flag.
  bool PutPaddedString(string_view v, int w, int p, bool l);

  template <typename T>
  T Wrap() {
    return T(this);
  }

  template <typename T>
  static FormatSinkImpl* Extract(T* s) {
    return s->sink_;
  }

 private:
  size_t Avail() const { return buf_ + sizeof(buf_) - pos_; }

  FormatRawSinkImpl raw_;
  size_t size_ = 0;
  char* pos_ = buf_;
  char buf_[1024];
};

struct Flags {
  bool basic : 1;     // fastest conversion: no flags, width, or precision
  bool left : 1;      // "-"
  bool show_pos : 1;  // "+"
  bool sign_col : 1;  // " "
  bool alt : 1;       // "#"
  bool zero : 1;      // "0"
  std::string ToString() const;
  friend std::ostream& operator<<(std::ostream& os, const Flags& v) {
    return os << v.ToString();
  }
};

struct LengthMod {
 public:
  enum Id : uint8_t {
    h, hh, l, ll, L, j, z, t, q, none
  };
  static const size_t kNumValues = none + 1;

  LengthMod() : id_(none) {}

  // Index into the opaque array of LengthMod enums.
  // Requires: i < kNumValues
  static LengthMod FromIndex(size_t i) {
    return LengthMod(kSpecs[i].value);
  }

  static LengthMod FromId(Id id) { return LengthMod(id); }

  // The length modifier std::string associated with a specified LengthMod.
  string_view name() const {
    const Spec& spec = kSpecs[id_];
    return {spec.name, spec.name_length};
  }

  Id id() const { return id_; }

  friend bool operator==(const LengthMod& a, const LengthMod& b) {
    return a.id() == b.id();
  }
  friend bool operator!=(const LengthMod& a, const LengthMod& b) {
    return !(a == b);
  }
  friend std::ostream& operator<<(std::ostream& os, const LengthMod& v) {
    return os << v.name();
  }

 private:
  struct Spec {
    Id value;
    const char *name;
    size_t name_length;
  };
  static const Spec kSpecs[];

  explicit LengthMod(Id id) : id_(id) {}

  Id id_;
};

// clang-format off
#define ABSL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \
  /* text */ \
  X_VAL(c) X_SEP X_VAL(C) X_SEP X_VAL(s) X_SEP X_VAL(S) X_SEP \
  /* ints */ \
  X_VAL(d) X_SEP X_VAL(i) X_SEP X_VAL(o) X_SEP \
  X_VAL(u) X_SEP X_VAL(x) X_SEP X_VAL(X) X_SEP \
  /* floats */ \
  X_VAL(f) X_SEP X_VAL(F) X_SEP X_VAL(e) X_SEP X_VAL(E) X_SEP \
  X_VAL(g) X_SEP X_VAL(G) X_SEP X_VAL(a) X_SEP X_VAL(A) X_SEP \
  /* misc */ \
  X_VAL(n) X_SEP X_VAL(p)
// clang-format on

struct ConversionChar {
 public:
  enum Id : uint8_t {
    c, C, s, S,              // text
    d, i, o, u, x, X,        // int
    f, F, e, E, g, G, a, A,  // float
    n, p,                    // misc
    none
  };
  static const size_t kNumValues = none + 1;

  ConversionChar() : id_(none) {}

 public:
  // Index into the opaque array of ConversionChar enums.
  // Requires: i < kNumValues
  static ConversionChar FromIndex(size_t i) {
    return ConversionChar(kSpecs[i].value);
  }

  static ConversionChar FromChar(char c) {
    ConversionChar::Id out_id = ConversionChar::none;
    switch (c) {
#define X_VAL(id)                \
  case #id[0]:                   \
    out_id = ConversionChar::id; \
    break;
      ABSL_CONVERSION_CHARS_EXPAND_(X_VAL, )
#undef X_VAL
      default:
        break;
    }
    return ConversionChar(out_id);
  }

  static ConversionChar FromId(Id id) { return ConversionChar(id); }
  Id id() const { return id_; }

  int radix() const {
    switch (id()) {
      case x: case X: case a: case A: case p: return 16;
      case o: return 8;
      default: return 10;
    }
  }

  bool upper() const {
    switch (id()) {
      case X: case F: case E: case G: case A: return true;
      default: return false;
    }
  }

  bool is_signed() const {
    switch (id()) {
      case d: case i: return true;
      default: return false;
    }
  }

  bool is_integral() const {
    switch (id()) {
      case d: case i: case u: case o: case x: case X:
        return true;
      default: return false;
    }
  }

  bool is_float() const {
    switch (id()) {
      case a: case e: case f: case g: case A: case E: case F: case G:
        return true;
      default: return false;
    }
  }

  bool IsValid() const { return id() != none; }

  // The associated char.
  char Char() const { return kSpecs[id_].name; }

  friend bool operator==(const ConversionChar& a, const ConversionChar& b) {
    return a.id() == b.id();
  }
  friend bool operator!=(const ConversionChar& a, const ConversionChar& b) {
    return !(a == b);
  }
  friend std::ostream& operator<<(std::ostream& os, const ConversionChar& v) {
    char c = v.Char();
    if (!c) c = '?';
    return os << c;
  }

 private:
  struct Spec {
    Id value;
    char name;
  };
  static const Spec kSpecs[];

  explicit ConversionChar(Id id) : id_(id) {}

  Id id_;
};

class ConversionSpec {
 public:
  Flags flags() const { return flags_; }
  LengthMod length_mod() const { return length_mod_; }
  ConversionChar conv() const { return conv_; }

  // Returns the specified width. If width is unspecfied, it returns a negative
  // value.
  int width() const { return width_; }
  // Returns the specified precision. If precision is unspecfied, it returns a
  // negative value.
  int precision() const { return precision_; }

  void set_flags(Flags f) { flags_ = f; }
  void set_length_mod(LengthMod lm) { length_mod_ = lm; }
  void set_conv(ConversionChar c) { conv_ = c; }
  void set_width(int w) { width_ = w; }
  void set_precision(int p) { precision_ = p; }
  void set_left(bool b) { flags_.left = b; }

 private:
  Flags flags_;
  LengthMod length_mod_;
  ConversionChar conv_;
  int width_;
  int precision_;
};

constexpr uint64_t ConversionCharToConvValue(char conv) {
  return
#define CONV_SET_CASE(c) \
  conv == #c[0] ? (uint64_t{1} << (1 + ConversionChar::Id::c)):
      ABSL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, )
#undef CONV_SET_CASE
                  conv == '*'
          ? 1
          : 0;
}

enum class Conv : uint64_t {
#define CONV_SET_CASE(c) c = ConversionCharToConvValue(#c[0]),
  ABSL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, )
#undef CONV_SET_CASE

  // Used for width/precision '*' specification.
  star = ConversionCharToConvValue('*'),

  // Some predefined values:
  integral = d | i | u | o | x | X,
  floating = a | e | f | g | A | E | F | G,
  numeric = integral | floating,
  string = s,  // absl:ignore(std::string)
  pointer = p
};

// Type safe OR operator.
// We need this for two reasons:
//  1. operator| on enums makes them decay to integers and the result is an
//     integer. We need the result to stay as an enum.
//  2. We use "enum class" which would not work even if we accepted the decay.
constexpr Conv operator|(Conv a, Conv b) {
  return Conv(static_cast<uint64_t>(a) | static_cast<uint64_t>(b));
}

// Get a conversion with a single character in it.
constexpr Conv ConversionCharToConv(char c) {
  return Conv(ConversionCharToConvValue(c));
}

// Checks whether `c` exists in `set`.
constexpr bool Contains(Conv set, char c) {
  return (static_cast<uint64_t>(set) & ConversionCharToConvValue(c)) != 0;
}

// Checks whether all the characters in `c` are contained in `set`
constexpr bool Contains(Conv set, Conv c) {
  return (static_cast<uint64_t>(set) & static_cast<uint64_t>(c)) ==
         static_cast<uint64_t>(c);
}

// Return type of the AbslFormatConvert() functions.
// The Conv template parameter is used to inform the framework of what
// conversion characters are supported by that AbslFormatConvert routine.
template <Conv C>
struct ConvertResult {
  static constexpr Conv kConv = C;
  bool value;
};
template <Conv C>
constexpr Conv ConvertResult<C>::kConv;

// Return capacity - used, clipped to a minimum of 0.
inline size_t Excess(size_t used, size_t capacity) {
  return used < capacity ? capacity - used : 0;
}

}  // namespace str_format_internal

}  // namespace absl

#endif  // ABSL_STRINGS_STR_FORMAT_EXTENSION_H_
