// -*- 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_SYNCSTREAM
#define _LIBCPP_SYNCSTREAM

/*
    syncstream synopsis

#include <ostream>  // see [ostream.syn]

namespace std {
    template<class charT, class traits, class Allocator>
    class basic_syncbuf;

    // [syncstream.syncbuf.special], specialized algorithms
    template<class charT, class traits, class Allocator>
      void swap(basic_syncbuf<charT, traits, Allocator>&,
                basic_syncbuf<charT, traits, Allocator>&);

    using syncbuf = basic_syncbuf<char>;
    using wsyncbuf = basic_syncbuf<wchar_t>;

    template<class charT, class traits, class Allocator>
    class basic_osyncstream;

    using osyncstream = basic_osyncstream<char>;
    using wosyncstream = basic_osyncstream<wchar_t>;

    template<class charT, class traits, class Allocator>
    class basic_syncbuf : public basic_streambuf<charT, traits> {
    public:
        using char_type      = charT;
        using int_type       = typename traits::int_type;
        using pos_type       = typename traits::pos_type;
        using off_type       = typename traits::off_type;
        using traits_type    = traits;
        using allocator_type = Allocator;

        using streambuf_type = basic_streambuf<charT, traits>;

        // [syncstream.syncbuf.cons], construction and destruction
        basic_syncbuf()
          : basic_syncbuf(nullptr) {}
        explicit basic_syncbuf(streambuf_type* obuf)
          : basic_syncbuf(obuf, Allocator()) {}
        basic_syncbuf(streambuf_type*, const Allocator&);
        basic_syncbuf(basic_syncbuf&&);
        ~basic_syncbuf();

        // [syncstream.syncbuf.assign], assignment and swap
        basic_syncbuf& operator=(basic_syncbuf&&);
        void swap(basic_syncbuf&);

        // [syncstream.syncbuf.members], member functions
        bool emit();
        streambuf_type* get_wrapped() const noexcept;
        allocator_type get_allocator() const noexcept;
        void set_emit_on_sync(bool) noexcept;

    protected:
        // [syncstream.syncbuf.virtuals], overridden virtual functions
        int sync() override;

    private:
        streambuf_type* wrapped;    // exposition only
        bool emit_on_sync{};        // exposition only
    };

    // [syncstream.syncbuf.special], specialized algorithms
    template<class charT, class traits, class Allocator>
    void swap(basic_syncbuf<charT, traits, Allocator>&,
              basic_syncbuf<charT, traits, Allocator>&);

    template<class charT, class traits, class Allocator>
    class basic_osyncstream : public basic_ostream<charT, traits> {
    public:
        using char_type   = charT;
        using int_type    = typename traits::int_type;
        using pos_type    = typename traits::pos_type;
        using off_type    = typename traits::off_type;
        using traits_type = traits;

        using allocator_type = Allocator;
        using streambuf_type = basic_streambuf<charT, traits>;
        using syncbuf_type   = basic_syncbuf<charT, traits, Allocator>;

        // [syncstream.osyncstream.cons], construction and destruction
        basic_osyncstream(streambuf_type*, const Allocator&);
        explicit basic_osyncstream(streambuf_type* obuf)
          : basic_osyncstream(obuf, Allocator()) {}
        basic_osyncstream(basic_ostream<charT, traits>& os, const Allocator& allocator)
          : basic_osyncstream(os.rdbuf(), allocator) {}
        explicit basic_osyncstream(basic_ostream<charT, traits>& os)
          : basic_osyncstream(os, Allocator()) {}
        basic_osyncstream(basic_osyncstream&&) noexcept;
        ~basic_osyncstream();

        // [syncstream.osyncstream.assign], assignment
        basic_osyncstream& operator=(basic_osyncstream&&);

        // [syncstream.osyncstream.members], member functions
        void emit();
        streambuf_type* get_wrapped() const noexcept;
        syncbuf_type* rdbuf() const noexcept { return const_cast<syncbuf_type*>(addressof(sb)); }

    private:
        syncbuf_type sb;    // exposition only
    };
}

*/

#include <__config>

#if _LIBCPP_HAS_LOCALIZATION

#  include <__mutex/lock_guard.h>
#  include <__utility/move.h>
#  include <ios>
#  include <iosfwd> // required for declaration of default arguments
#  include <streambuf>
#  include <string>

#  if _LIBCPP_HAS_THREADS
#    include <map>
#    include <shared_mutex>
#  endif

// standard-mandated includes

// [syncstream.syn]
#  include <ostream>

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

_LIBCPP_PUSH_MACROS
#  include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

#  if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM)

// [syncstream.syncbuf.overview]/1
//   Class template basic_syncbuf stores character data written to it,
//   known as the associated output, into internal buffers allocated
//   using the object's allocator. The associated output is transferred
//   to the wrapped stream buffer object *wrapped when emit() is called
//   or when the basic_syncbuf object is destroyed. Such transfers are
//   atomic with respect to transfers by other basic_syncbuf objects
//   with the same wrapped stream buffer object.
//
// This helper singleton is used to implement the required
// synchronisation guarantees.
#    if _LIBCPP_HAS_THREADS
class __wrapped_streambuf_mutex {
  _LIBCPP_HIDE_FROM_ABI __wrapped_streambuf_mutex() = default;

public:
  __wrapped_streambuf_mutex(const __wrapped_streambuf_mutex&)            = delete;
  __wrapped_streambuf_mutex& operator=(const __wrapped_streambuf_mutex&) = delete;

  _LIBCPP_HIDE_FROM_ABI void __inc_reference([[maybe_unused]] void* __ptr) {
    _LIBCPP_ASSERT_INTERNAL(__ptr != nullptr, "non-wrapped streambufs are never written to");
    unique_lock __lock{__mutex_};
    ++__lut_[reinterpret_cast<uintptr_t>(__ptr)].__count;
  }

  // pre: __ptr is in __lut_
  _LIBCPP_HIDE_FROM_ABI void __dec_reference([[maybe_unused]] void* __ptr) noexcept {
    unique_lock __lock{__mutex_};

    auto __it = __get_it(__ptr);
    if (__it->second.__count == 1)
      __lut_.erase(__it);
    else
      --__it->second.__count;
  }

  // TODO
  // This function causes emit() aquire two mutexes:
  // - __mutex_ shared
  // _ __get_it(__ptr)->second.__mutex exclusive
  //
  // Instead store a pointer to __get_it(__ptr)->second.__mutex when
  // calling __inc_reference.
  //
  // pre: __ptr is in __lut_
  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI lock_guard<mutex> __get_lock([[maybe_unused]] void* __ptr) noexcept {
    shared_lock __lock{__mutex_};
    return lock_guard{__get_it(__ptr)->second.__mutex};
  }

  // This function is used for testing.
  //
  // It is allowed to call this function with a non-registered pointer.
  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __get_count([[maybe_unused]] void* __ptr) noexcept {
    _LIBCPP_ASSERT_INTERNAL(__ptr != nullptr, "non-wrapped streambufs are never written to");
    shared_lock __lock{__mutex_};

    auto __it = __lut_.find(reinterpret_cast<uintptr_t>(__ptr));
    return __it != __lut_.end() ? __it->second.__count : 0;
  }

  [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI __wrapped_streambuf_mutex& __instance() noexcept {
    static __wrapped_streambuf_mutex __result;
    return __result;
  }

private:
  struct __value {
    mutex __mutex;
    size_t __count{0};
  };

  shared_mutex __mutex_;
  map<uintptr_t, __value> __lut_;

  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI map<uintptr_t, __value>::iterator __get_it(void* __ptr) noexcept {
    _LIBCPP_ASSERT_INTERNAL(__ptr != nullptr, "non-wrapped streambufs are never written to");

    auto __it = __lut_.find(reinterpret_cast<uintptr_t>(__ptr));
    _LIBCPP_ASSERT_INTERNAL(__it != __lut_.end(), "using a wrapped streambuf that has not been registered");
    _LIBCPP_ASSERT_INTERNAL(__it->second.__count >= 1, "found an inactive streambuf wrapper");
    return __it;
  }
};
#    endif // _LIBCPP_HAS_THREADS

// basic_syncbuf

// The class uses a basic_string<_CharT, _Traits, _Allocator> as
// internal buffer. Per [syncstream.syncbuf.cons]/4
//   Remarks: A copy of allocator is used to allocate memory for
//   internal buffers holding the associated output.
//
// Therefore the allocator used in the constructor is passed to the
// basic_string. The class does not keep a copy of this allocator.
template <class _CharT, class _Traits, class _Allocator>
class _LIBCPP_TEMPLATE_VIS basic_syncbuf : public basic_streambuf<_CharT, _Traits> {
public:
  using char_type      = _CharT;
  using traits_type    = _Traits;
  using int_type       = typename traits_type::int_type;
  using pos_type       = typename traits_type::pos_type;
  using off_type       = typename traits_type::off_type;
  using allocator_type = _Allocator;

  using streambuf_type = basic_streambuf<_CharT, _Traits>;

  // [syncstream.syncbuf.cons], construction and destruction

  _LIBCPP_HIDE_FROM_ABI basic_syncbuf() : basic_syncbuf(nullptr) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_syncbuf(streambuf_type* __obuf) : basic_syncbuf(__obuf, _Allocator()) {}

  _LIBCPP_HIDE_FROM_ABI basic_syncbuf(streambuf_type* __obuf, _Allocator const& __alloc)
      : __wrapped_(__obuf), __str_(__alloc) {
    __inc_reference();
  }

  _LIBCPP_HIDE_FROM_ABI basic_syncbuf(basic_syncbuf&& __other)
      : __wrapped_(__other.get_wrapped()), __str_(std::move(__other.__str_)), __emit_on_sync_(__other.__emit_on_sync_) {
    __move_common(__other);
  }

  _LIBCPP_HIDE_FROM_ABI ~basic_syncbuf() {
#    if _LIBCPP_HAS_EXCEPTIONS
    try {
#    endif // _LIBCPP_HAS_EXCEPTIONS
      emit();
#    if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
    }
#    endif // _LIBCPP_HAS_EXCEPTIONS
    __dec_reference();
  }

  // [syncstream.syncbuf.assign], assignment and swap

  _LIBCPP_HIDE_FROM_ABI basic_syncbuf& operator=(basic_syncbuf&& __other) {
    // The function is specified to call emit. This call should
    // propagate the exception thrown.
    emit();
    __dec_reference();

    __wrapped_      = __other.get_wrapped();
    __str_          = std::move(__other.__str_);
    __emit_on_sync_ = __other.__emit_on_sync_;

    __move_common(__other);

    return *this;
  }

  _LIBCPP_HIDE_FROM_ABI void swap(basic_syncbuf& __other) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
        allocator_traits<_Allocator>::propagate_on_container_swap::value || get_allocator() == __other.get_allocator(),
        "violates the mandated swap precondition");

    basic_syncbuf __tmp(std::move(__other));
    __other = std::move(*this);
    *this   = std::move(__tmp);
  }

  // [syncstream.syncbuf.members], member functions

  _LIBCPP_HIDE_FROM_ABI bool emit() { return emit(false); }

  _LIBCPP_HIDE_FROM_ABI streambuf_type* get_wrapped() const noexcept { return __wrapped_; }

  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }

  _LIBCPP_HIDE_FROM_ABI void set_emit_on_sync(bool __b) noexcept { __emit_on_sync_ = __b; }

protected:
  // [syncstream.syncbuf.virtuals], overridden virtual functions

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL
  int sync() override {
    if (__emit_on_sync_ && !emit(true))
      return -1;
    return 0;
  }

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL
  int_type overflow(int_type __c = traits_type::eof()) override {
    if (traits_type::eq_int_type(__c, traits_type::eof()))
      return traits_type::not_eof(__c);

    if (this->pptr() == this->epptr()) {
#    if _LIBCPP_HAS_EXCEPTIONS
      try {
#    endif
        size_t __size = __str_.size();
        __str_.resize(__str_.capacity() + 1);
        _LIBCPP_ASSERT_INTERNAL(__str_.size() > __size, "the buffer hasn't grown");

        char_type* __p = static_cast<char_type*>(__str_.data());
        this->setp(__p, __p + __str_.size());
        this->pbump(__size);

#    if _LIBCPP_HAS_EXCEPTIONS
      } catch (...) {
        return traits_type::eof();
      }
#    endif
    }

    return this->sputc(traits_type::to_char_type(__c));
  }

private:
  streambuf_type* __wrapped_;

  // TODO Use a more generic buffer.
  // That buffer should be light with almost no additional headers. Then
  // it can be use here, the __retarget_buffer, and place that use
  // the now removed get_temporary_buffer

  basic_string<_CharT, _Traits, _Allocator> __str_;
  bool __emit_on_sync_{false};

  _LIBCPP_HIDE_FROM_ABI bool emit(bool __flush) {
    if (!__wrapped_)
      return false;

#    if _LIBCPP_HAS_THREADS
    lock_guard<mutex> __lock = __wrapped_streambuf_mutex::__instance().__get_lock(__wrapped_);
#    endif

    bool __result = true;
    if (this->pptr() != this->pbase()) {
      _LIBCPP_ASSERT_INTERNAL(this->pbase() && this->pptr() && this->epptr(), "all put area pointers shold be valid");

      // The __str_ does not know how much of its buffer is used. This
      // information is extracted from the information of the base class.
      __result &= (__wrapped_->sputn(this->pbase(), this->pptr() - this->pbase()) != -1);
      // Clears the buffer, but keeps the contents (and) size of the
      // internal buffer.
      this->setp(this->pbase(), this->epptr());
    }

    if (__flush)
      __result &= (__wrapped_->pubsync() != -1);

    return __result;
  }

  _LIBCPP_HIDE_FROM_ABI void __move_common(basic_syncbuf& __other) {
    // Adjust the put area pointers to our buffer.
    char_type* __p = static_cast<char_type*>(__str_.data());
    this->setp(__p, __p + __str_.size());
    this->pbump(__other.pptr() - __other.pbase());

    // Clear __other_ so the destructor will act as a NOP.
    __other.setp(nullptr, nullptr);
    __other.__wrapped_ = nullptr;
  }

  _LIBCPP_HIDE_FROM_ABI void __inc_reference() {
#    if _LIBCPP_HAS_THREADS
    if (__wrapped_)
      __wrapped_streambuf_mutex::__instance().__inc_reference(__wrapped_);
#    endif
  }

  _LIBCPP_HIDE_FROM_ABI void __dec_reference() noexcept {
#    if _LIBCPP_HAS_THREADS
    if (__wrapped_)
      __wrapped_streambuf_mutex::__instance().__dec_reference(__wrapped_);
#    endif
  }
};

using std::syncbuf;
#    if _LIBCPP_HAS_WIDE_CHARACTERS
using std::wsyncbuf;
#    endif

// [syncstream.syncbuf.special], specialized algorithms
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI void
swap(basic_syncbuf<_CharT, _Traits, _Allocator>& __lhs, basic_syncbuf<_CharT, _Traits, _Allocator>& __rhs) {
  __lhs.swap(__rhs);
}

// basic_osyncstream

template <class _CharT, class _Traits, class _Allocator>
class _LIBCPP_TEMPLATE_VIS basic_osyncstream : public basic_ostream<_CharT, _Traits> {
public:
  using char_type   = _CharT;
  using traits_type = _Traits;
  using int_type    = typename traits_type::int_type;
  using pos_type    = typename traits_type::pos_type;
  using off_type    = typename traits_type::off_type;

  using allocator_type = _Allocator;
  using streambuf_type = basic_streambuf<char_type, traits_type>;
  using syncbuf_type   = basic_syncbuf<char_type, traits_type, allocator_type>;

  // [syncstream.osyncstream.cons], construction and destruction

  _LIBCPP_HIDE_FROM_ABI basic_osyncstream(streambuf_type* __obuf, allocator_type const& __alloc)
      : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__obuf, __alloc) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_osyncstream(streambuf_type* __obuf)
      : basic_osyncstream(__obuf, allocator_type()) {}

  _LIBCPP_HIDE_FROM_ABI basic_osyncstream(basic_ostream<char_type, traits_type>& __os, allocator_type const& __alloc)
      : basic_osyncstream(__os.rdbuf(), __alloc) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_osyncstream(basic_ostream<char_type, traits_type>& __os)
      : basic_osyncstream(__os, allocator_type()) {}

  _LIBCPP_HIDE_FROM_ABI basic_osyncstream(basic_osyncstream&& __other) noexcept
      : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__other.__sb_)) {
    this->set_rdbuf(std::addressof(__sb_));
  }

  // [syncstream.osyncstream.assign], assignment

  _LIBCPP_HIDE_FROM_ABI basic_osyncstream& operator=(basic_osyncstream&& __other) = default;

  // [syncstream.osyncstream.members], member functions

  _LIBCPP_HIDE_FROM_ABI void emit() {
    // The basic_ostream::put places the sentry in a try
    // catch, this does not match the wording of the standard
    // [ostream.unformatted]
    // TODO validate other unformatted output functions.
    typename basic_ostream<char_type, traits_type>::sentry __s(*this);
    if (__s) {
#    if _LIBCPP_HAS_EXCEPTIONS
      try {
#    endif

        if (__sb_.emit() == false)
          this->setstate(ios::badbit);
#    if _LIBCPP_HAS_EXCEPTIONS
      } catch (...) {
        this->__set_badbit_and_consider_rethrow();
      }
#    endif
    }
  }

  _LIBCPP_HIDE_FROM_ABI streambuf_type* get_wrapped() const noexcept { return __sb_.get_wrapped(); }

  _LIBCPP_HIDE_FROM_ABI syncbuf_type* rdbuf() const noexcept {
    return const_cast<syncbuf_type*>(std::addressof(__sb_));
  }

private:
  syncbuf_type __sb_;
};

using std::osyncstream;
#    if _LIBCPP_HAS_WIDE_CHARACTERS
using std::wosyncstream;
#    endif

#  endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM)

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP_HAS_LOCALIZATION

#endif // _LIBCPP_SYNCSTREAM
