// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___FORMAT_FORMATTER_BOOL_H
#define _LIBCPP___FORMAT_FORMATTER_BOOL_H

#include <__availability>
#include <__config>
#include <__format/format_error.h>
#include <__format/format_fwd.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
#include <__format/parser_std_format_spec.h>
#include <string_view>

#ifndef _LIBCPP_HAS_NO_LOCALIZATION
#include <locale>
#endif

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

#if _LIBCPP_STD_VER > 17

// TODO FMT Remove this once we require compilers with proper C++20 support.
// If the compiler has no concepts support, the format header will be disabled.
// Without concepts support enable_if needs to be used and that too much effort
// to support compilers with partial C++20 support.
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)

namespace __format_spec {

template <class _CharT>
class _LIBCPP_TEMPLATE_VIS __parser_bool : public __parser_integral<_CharT> {
public:
  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx)
      -> decltype(__parse_ctx.begin()) {
    auto __it = __parser_integral<_CharT>::__parse(__parse_ctx);

    switch (this->__type) {
    case _Flags::_Type::__default:
      this->__type = _Flags::_Type::__string;
      [[fallthrough]];
    case _Flags::_Type::__string:
      this->__handle_bool();
      break;

    case _Flags::_Type::__char:
      this->__handle_char();
      break;

    case _Flags::_Type::__binary_lower_case:
    case _Flags::_Type::__binary_upper_case:
    case _Flags::_Type::__octal:
    case _Flags::_Type::__decimal:
    case _Flags::_Type::__hexadecimal_lower_case:
    case _Flags::_Type::__hexadecimal_upper_case:
      this->__handle_integer();
      break;

    default:
      __throw_format_error(
          "The format-spec type has a type not supported for a bool argument");
    }

    return __it;
  }
};

template <class _CharT>
struct _LIBCPP_TEMPLATE_VIS __bool_strings;

template <>
struct _LIBCPP_TEMPLATE_VIS __bool_strings<char> {
  static constexpr string_view __true{"true"};
  static constexpr string_view __false{"false"};
};

template <>
struct _LIBCPP_TEMPLATE_VIS __bool_strings<wchar_t> {
  static constexpr wstring_view __true{L"true"};
  static constexpr wstring_view __false{L"false"};
};

template <class _CharT>
using __formatter_bool = __formatter_integral<__parser_bool<_CharT>>;

} //namespace __format_spec

// [format.formatter.spec]/2.3
// For each charT, for each cv-unqualified arithmetic type ArithmeticT other
// than char, wchar_t, char8_t, char16_t, or char32_t, a specialization

template <class _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<bool, _CharT>
    : public __format_spec::__formatter_bool<_CharT> {
  using _Base = __format_spec::__formatter_bool<_CharT>;

  _LIBCPP_HIDE_FROM_ABI auto format(bool __value, auto& __ctx)
      -> decltype(__ctx.out()) {
    if (this->__type != __format_spec::_Flags::_Type::__string)
      return _Base::format(static_cast<unsigned char>(__value), __ctx);

    if (this->__width_needs_substitution())
      this->__substitute_width_arg_id(__ctx.arg(this->__width));

#ifndef _LIBCPP_HAS_NO_LOCALIZATION
    if (this->__locale_specific_form) {
      const auto& __np = use_facet<numpunct<_CharT>>(__ctx.locale());
      basic_string<_CharT> __str = __value ? __np.truename() : __np.falsename();
      return __formatter::__write_unicode(
          __ctx.out(), basic_string_view<_CharT>{__str}, this->__width, -1,
          this->__fill, this->__alignment);
    }
#endif
    basic_string_view<_CharT> __str =
        __value ? __format_spec::__bool_strings<_CharT>::__true
                : __format_spec::__bool_strings<_CharT>::__false;

    // The output only uses ASCII so every character is one column.
    unsigned __size = __str.size();
    if (__size >= this->__width)
      return _VSTD::copy(__str.begin(), __str.end(), __ctx.out());

    return __formatter::__write(__ctx.out(), __str.begin(), __str.end(), __size,
                                this->__width, this->__fill, this->__alignment);
  }
};

#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)

#endif //_LIBCPP_STD_VER > 17

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___FORMAT_FORMATTER_BOOL_H
