#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_

#include "absl/strings/internal/str_format/arg.h"
#include "absl/strings/internal/str_format/extension.h"

// Compile time check support for entry points.

#ifndef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
#if defined(__clang__) && !defined(__native_client__)
#if __has_attribute(enable_if)
#define ABSL_INTERNAL_ENABLE_FORMAT_CHECKER 1
#endif  // __has_attribute(enable_if)
#endif  // defined(__clang__) && !defined(__native_client__)
#endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER

namespace absl {
inline namespace lts_2018_12_18 {
namespace str_format_internal {

constexpr bool AllOf() { return true; }

template <typename... T>
constexpr bool AllOf(bool b, T... t) {
  return b && AllOf(t...);
}

template <typename Arg>
constexpr Conv ArgumentToConv() {
  return decltype(str_format_internal::FormatConvertImpl(
      std::declval<const Arg&>(), std::declval<const ConversionSpec&>(),
      std::declval<FormatSinkImpl*>()))::kConv;
}

#if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER

constexpr bool ContainsChar(const char* chars, char c) {
  return *chars == c || (*chars && ContainsChar(chars + 1, c));
}

// A constexpr compatible list of Convs.
struct ConvList {
  const Conv* array;
  int count;

  // We do the bound check here to avoid having to do it on the callers.
  // Returning an empty Conv has the same effect as short circuiting because it
  // will never match any conversion.
  constexpr Conv operator[](int i) const {
    return i < count ? array[i] : Conv{};
  }

  constexpr ConvList without_front() const {
    return count != 0 ? ConvList{array + 1, count - 1} : *this;
  }
};

template <size_t count>
struct ConvListT {
  // Make sure the array has size > 0.
  Conv list[count ? count : 1];
};

constexpr char GetChar(string_view str, size_t index) {
  return index < str.size() ? str[index] : char{};
}

constexpr string_view ConsumeFront(string_view str, size_t len = 1) {
  return len <= str.size() ? string_view(str.data() + len, str.size() - len)
                           : string_view();
}

constexpr string_view ConsumeAnyOf(string_view format, const char* chars) {
  return ContainsChar(chars, GetChar(format, 0))
             ? ConsumeAnyOf(ConsumeFront(format), chars)
             : format;
}

constexpr bool IsDigit(char c) { return c >= '0' && c <= '9'; }

// Helper class for the ParseDigits function.
// It encapsulates the two return values we need there.
struct Integer {
  string_view format;
  int value;

  // If the next character is a '$', consume it.
  // Otherwise, make `this` an invalid positional argument.
  constexpr Integer ConsumePositionalDollar() const {
    return GetChar(format, 0) == '$' ? Integer{ConsumeFront(format), value}
                                     : Integer{format, 0};
  }
};

constexpr Integer ParseDigits(string_view format, int value = 0) {
  return IsDigit(GetChar(format, 0))
             ? ParseDigits(ConsumeFront(format),
                           10 * value + GetChar(format, 0) - '0')
             : Integer{format, value};
}

// Parse digits for a positional argument.
// The parsing also consumes the '$'.
constexpr Integer ParsePositional(string_view format) {
  return ParseDigits(format).ConsumePositionalDollar();
}

// Parses a single conversion specifier.
// See ConvParser::Run() for post conditions.
class ConvParser {
  constexpr ConvParser SetFormat(string_view format) const {
    return ConvParser(format, args_, error_, arg_position_, is_positional_);
  }

  constexpr ConvParser SetArgs(ConvList args) const {
    return ConvParser(format_, args, error_, arg_position_, is_positional_);
  }

  constexpr ConvParser SetError(bool error) const {
    return ConvParser(format_, args_, error_ || error, arg_position_,
                      is_positional_);
  }

  constexpr ConvParser SetArgPosition(int arg_position) const {
    return ConvParser(format_, args_, error_, arg_position, is_positional_);
  }

  // Consumes the next arg and verifies that it matches `conv`.
  // `error_` is set if there is no next arg or if it doesn't match `conv`.
  constexpr ConvParser ConsumeNextArg(char conv) const {
    return SetArgs(args_.without_front()).SetError(!Contains(args_[0], conv));
  }

  // Verify that positional argument `i.value` matches `conv`.
  // `error_` is set if `i.value` is not a valid argument or if it doesn't
  // match.
  constexpr ConvParser VerifyPositional(Integer i, char conv) const {
    return SetFormat(i.format).SetError(!Contains(args_[i.value - 1], conv));
  }

  // Parse the position of the arg and store it in `arg_position_`.
  constexpr ConvParser ParseArgPosition(Integer arg) const {
    return SetFormat(arg.format).SetArgPosition(arg.value);
  }

  // Consume the flags.
  constexpr ConvParser ParseFlags() const {
    return SetFormat(ConsumeAnyOf(format_, "-+ #0"));
  }

  // Consume the width.
  // If it is '*', we verify that it matches `args_`. `error_` is set if it
  // doesn't match.
  constexpr ConvParser ParseWidth() const {
    return IsDigit(GetChar(format_, 0))
               ? SetFormat(ParseDigits(format_).format)
               : GetChar(format_, 0) == '*'
                     ? is_positional_
                           ? VerifyPositional(
                                 ParsePositional(ConsumeFront(format_)), '*')
                           : SetFormat(ConsumeFront(format_))
                                 .ConsumeNextArg('*')
                     : *this;
  }

  // Consume the precision.
  // If it is '*', we verify that it matches `args_`. `error_` is set if it
  // doesn't match.
  constexpr ConvParser ParsePrecision() const {
    return GetChar(format_, 0) != '.'
               ? *this
               : GetChar(format_, 1) == '*'
                     ? is_positional_
                           ? VerifyPositional(
                                 ParsePositional(ConsumeFront(format_, 2)), '*')
                           : SetFormat(ConsumeFront(format_, 2))
                                 .ConsumeNextArg('*')
                     : SetFormat(ParseDigits(ConsumeFront(format_)).format);
  }

  // Consume the length characters.
  constexpr ConvParser ParseLength() const {
    return SetFormat(ConsumeAnyOf(format_, "lLhjztq"));
  }

  // Consume the conversion character and verify that it matches `args_`.
  // `error_` is set if it doesn't match.
  constexpr ConvParser ParseConversion() const {
    return is_positional_
               ? VerifyPositional({ConsumeFront(format_), arg_position_},
                                  GetChar(format_, 0))
               : ConsumeNextArg(GetChar(format_, 0))
                     .SetFormat(ConsumeFront(format_));
  }

  constexpr ConvParser(string_view format, ConvList args, bool error,
                       int arg_position, bool is_positional)
      : format_(format),
        args_(args),
        error_(error),
        arg_position_(arg_position),
        is_positional_(is_positional) {}

 public:
  constexpr ConvParser(string_view format, ConvList args, bool is_positional)
      : format_(format),
        args_(args),
        error_(false),
        arg_position_(0),
        is_positional_(is_positional) {}

  // Consume the whole conversion specifier.
  // `format()` will be set to the character after the conversion character.
  // `error()` will be set if any of the arguments do not match.
  constexpr ConvParser Run() const {
    return (is_positional_ ? ParseArgPosition(ParsePositional(format_)) : *this)
        .ParseFlags()
        .ParseWidth()
        .ParsePrecision()
        .ParseLength()
        .ParseConversion();
  }

  constexpr string_view format() const { return format_; }
  constexpr ConvList args() const { return args_; }
  constexpr bool error() const { return error_; }
  constexpr bool is_positional() const { return is_positional_; }

 private:
  string_view format_;
  // Current list of arguments. If we are not in positional mode we will consume
  // from the front.
  ConvList args_;
  bool error_;
  // Holds the argument position of the conversion character, if we are in
  // positional mode. Otherwise, it is unspecified.
  int arg_position_;
  // Whether we are in positional mode.
  // It changes the behavior of '*' and where to find the converted argument.
  bool is_positional_;
};

// Parses a whole format expression.
// See FormatParser::Run().
class FormatParser {
  static constexpr bool FoundPercent(string_view format) {
    return format.empty() ||
           (GetChar(format, 0) == '%' && GetChar(format, 1) != '%');
  }

  // We use an inner function to increase the recursion limit.
  // The inner function consumes up to `limit` characters on every run.
  // This increases the limit from 512 to ~512*limit.
  static constexpr string_view ConsumeNonPercentInner(string_view format,
                                                      int limit = 20) {
    return FoundPercent(format) || !limit
               ? format
               : ConsumeNonPercentInner(
                     ConsumeFront(format, GetChar(format, 0) == '%' &&
                                                  GetChar(format, 1) == '%'
                                              ? 2
                                              : 1),
                     limit - 1);
  }

  // Consume characters until the next conversion spec %.
  // It skips %%.
  static constexpr string_view ConsumeNonPercent(string_view format) {
    return FoundPercent(format)
               ? format
               : ConsumeNonPercent(ConsumeNonPercentInner(format));
  }

  static constexpr bool IsPositional(string_view format) {
    return IsDigit(GetChar(format, 0)) ? IsPositional(ConsumeFront(format))
                                       : GetChar(format, 0) == '$';
  }

  constexpr bool RunImpl(bool is_positional) const {
    // In non-positional mode we require all arguments to be consumed.
    // In positional mode just reaching the end of the format without errors is
    // enough.
    return (format_.empty() && (is_positional || args_.count == 0)) ||
           (!format_.empty() &&
            ValidateArg(
                ConvParser(ConsumeFront(format_), args_, is_positional).Run()));
  }

  constexpr bool ValidateArg(ConvParser conv) const {
    return !conv.error() && FormatParser(conv.format(), conv.args())
                                .RunImpl(conv.is_positional());
  }

 public:
  constexpr FormatParser(string_view format, ConvList args)
      : format_(ConsumeNonPercent(format)), args_(args) {}

  // Runs the parser for `format` and `args`.
  // It verifies that the format is valid and that all conversion specifiers
  // match the arguments passed.
  // In non-positional mode it also verfies that all arguments are consumed.
  constexpr bool Run() const {
    return RunImpl(!format_.empty() && IsPositional(ConsumeFront(format_)));
  }

 private:
  string_view format_;
  // Current list of arguments.
  // If we are not in positional mode we will consume from the front and will
  // have to be empty in the end.
  ConvList args_;
};

template <Conv... C>
constexpr bool ValidFormatImpl(string_view format) {
  return FormatParser(format,
                      {ConvListT<sizeof...(C)>{{C...}}.list, sizeof...(C)})
      .Run();
}

#endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER

}  // namespace str_format_internal
}  // inline namespace lts_2018_12_18
}  // namespace absl

#endif  // ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
