/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#pragma once

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

#include <cm3p/uv.h>

#include "cmUVHandlePtr.h"

/*
 * This file is based on example code from:
 *
 * https://web.archive.org/web/20170515211805/
 *     http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
 *
 * 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;
  std::size_t const 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, uv_buf_t const* /* 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>;
