/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#ifndef cmUVStreambuf_h
#define cmUVStreambuf_h

#include <algorithm>
#include <cstring>
#include <streambuf>
#include <vector>

#include "cm_uv.h"

#include "cmUVHandlePtr.h"

/*
 * This file is based on example code from:
 *
 * http://www.voidcn.com/article/p-vjnlygmc-gy.html
 *
 * The example code was distributed under the following license:
 *
 * Copyright 2007 Edd Dawson.
 * Distributed under the Boost Software License, Version 1.0.
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

template <typename CharT, typename Traits = std::char_traits<CharT>>
class cmBasicUVStreambuf : public std::basic_streambuf<CharT, Traits>
{
public:
  cmBasicUVStreambuf(std::size_t bufSize = 256, std::size_t putBack = 8);
  ~cmBasicUVStreambuf() override;

  bool is_open() const;

  cmBasicUVStreambuf* open(uv_stream_t* stream);

  cmBasicUVStreambuf* close();

protected:
  typename cmBasicUVStreambuf<CharT, Traits>::int_type underflow() override;
  std::streamsize showmanyc() override;

  // FIXME: Add write support

private:
  uv_stream_t* Stream = nullptr;
  void* OldStreamData = nullptr;
  const std::size_t PutBack = 0;
  std::vector<CharT> InputBuffer;
  bool EndOfFile = false;

  void StreamReadStartStop();

  void StreamRead(ssize_t nread);
  void HandleAlloc(uv_buf_t* buf);
};

template <typename CharT, typename Traits>
cmBasicUVStreambuf<CharT, Traits>::cmBasicUVStreambuf(std::size_t bufSize,
                                                      std::size_t putBack)
  : PutBack(std::max<std::size_t>(putBack, 1))
  , InputBuffer(std::max<std::size_t>(this->PutBack, bufSize) + this->PutBack)
{
  this->close();
}

template <typename CharT, typename Traits>
cmBasicUVStreambuf<CharT, Traits>::~cmBasicUVStreambuf()
{
  this->close();
}

template <typename CharT, typename Traits>
bool cmBasicUVStreambuf<CharT, Traits>::is_open() const
{
  return this->Stream != nullptr;
}

template <typename CharT, typename Traits>
cmBasicUVStreambuf<CharT, Traits>* cmBasicUVStreambuf<CharT, Traits>::open(
  uv_stream_t* stream)
{
  this->close();
  this->Stream = stream;
  this->EndOfFile = false;
  if (this->Stream) {
    this->OldStreamData = this->Stream->data;
    this->Stream->data = this;
  }
  this->StreamReadStartStop();
  return this;
}

template <typename CharT, typename Traits>
cmBasicUVStreambuf<CharT, Traits>* cmBasicUVStreambuf<CharT, Traits>::close()
{
  if (this->Stream) {
    uv_read_stop(this->Stream);
    this->Stream->data = this->OldStreamData;
  }
  this->Stream = nullptr;
  CharT* readEnd = this->InputBuffer.data() + this->InputBuffer.size();
  this->setg(readEnd, readEnd, readEnd);
  return this;
}

template <typename CharT, typename Traits>
typename cmBasicUVStreambuf<CharT, Traits>::int_type
cmBasicUVStreambuf<CharT, Traits>::underflow()
{
  if (!this->is_open()) {
    return Traits::eof();
  }

  if (this->gptr() < this->egptr()) {
    return Traits::to_int_type(*this->gptr());
  }

  this->StreamReadStartStop();
  while (this->in_avail() == 0) {
    uv_run(this->Stream->loop, UV_RUN_ONCE);
  }
  if (this->in_avail() == -1) {
    return Traits::eof();
  }
  return Traits::to_int_type(*this->gptr());
}

template <typename CharT, typename Traits>
std::streamsize cmBasicUVStreambuf<CharT, Traits>::showmanyc()
{
  if (!this->is_open() || this->EndOfFile) {
    return -1;
  }
  return 0;
}

template <typename CharT, typename Traits>
void cmBasicUVStreambuf<CharT, Traits>::StreamReadStartStop()
{
  if (this->Stream) {
    uv_read_stop(this->Stream);
    if (this->gptr() >= this->egptr()) {
      uv_read_start(
        this->Stream,
        [](uv_handle_t* handle, size_t /* unused */, uv_buf_t* buf) {
          auto streambuf =
            static_cast<cmBasicUVStreambuf<CharT, Traits>*>(handle->data);
          streambuf->HandleAlloc(buf);
        },
        [](uv_stream_t* stream2, ssize_t nread, const uv_buf_t* /* unused */) {
          auto streambuf =
            static_cast<cmBasicUVStreambuf<CharT, Traits>*>(stream2->data);
          streambuf->StreamRead(nread);
        });
    }
  }
}

template <typename CharT, typename Traits>
void cmBasicUVStreambuf<CharT, Traits>::HandleAlloc(uv_buf_t* buf)
{
  auto size = this->egptr() - this->gptr();
  std::memmove(this->InputBuffer.data(), this->gptr(),
               this->egptr() - this->gptr());
  this->setg(this->InputBuffer.data(), this->InputBuffer.data(),
             this->InputBuffer.data() + size);
  buf->base = this->egptr();
#ifdef _WIN32
#  define BUF_LEN_TYPE ULONG
#else
#  define BUF_LEN_TYPE size_t
#endif
  buf->len = BUF_LEN_TYPE(
    (this->InputBuffer.data() + this->InputBuffer.size() - this->egptr()) *
    sizeof(CharT));
#undef BUF_LEN_TYPE
}

template <typename CharT, typename Traits>
void cmBasicUVStreambuf<CharT, Traits>::StreamRead(ssize_t nread)
{
  if (nread > 0) {
    this->setg(this->eback(), this->gptr(),
               this->egptr() + nread / sizeof(CharT));
    uv_read_stop(this->Stream);
  } else if (nread < 0 /*|| nread == UV_EOF*/) {
    this->EndOfFile = true;
    uv_read_stop(this->Stream);
  }
}

using cmUVStreambuf = cmBasicUVStreambuf<char>;

#endif
