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

#include <@KWSYS_NAMESPACE@/Configure.hxx>

#include <@KWSYS_NAMESPACE@/Encoding.hxx>

#include <cstring>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <streambuf>
#include <string>

#if defined(_WIN32)
#  include <windows.h>
#  if __cplusplus >= 201103L
#    include <system_error>
#  endif
#endif

namespace @KWSYS_NAMESPACE@ {
#if defined(_WIN32)

template <class CharT, class Traits = std::char_traits<CharT> >
class BasicConsoleBuf : public std::basic_streambuf<CharT, Traits>
{
public:
  typedef typename Traits::int_type int_type;
  typedef typename Traits::char_type char_type;

  class Manager
  {
  public:
    Manager(std::basic_ios<CharT, Traits>& ios, const bool err = false)
      : m_consolebuf(0)
    {
      m_ios = &ios;
      try {
        m_consolebuf = new BasicConsoleBuf<CharT, Traits>(err);
        m_streambuf = m_ios->rdbuf(m_consolebuf);
      } catch (const std::runtime_error& ex) {
        std::cerr << "Failed to create ConsoleBuf!" << std::endl
                  << ex.what() << std::endl;
      };
    }

    BasicConsoleBuf<CharT, Traits>* GetConsoleBuf() { return m_consolebuf; }

    void SetUTF8Pipes()
    {
      if (m_consolebuf) {
        m_consolebuf->input_pipe_codepage = CP_UTF8;
        m_consolebuf->output_pipe_codepage = CP_UTF8;
        m_consolebuf->activateCodepageChange();
      }
    }

    ~Manager()
    {
      if (m_consolebuf) {
        delete m_consolebuf;
        m_ios->rdbuf(m_streambuf);
      }
    }

  private:
    std::basic_ios<CharT, Traits>* m_ios;
    std::basic_streambuf<CharT, Traits>* m_streambuf;
    BasicConsoleBuf<CharT, Traits>* m_consolebuf;
  };

  BasicConsoleBuf(const bool err = false)
    : flush_on_newline(true)
    , input_pipe_codepage(0)
    , output_pipe_codepage(0)
    , input_file_codepage(CP_UTF8)
    , output_file_codepage(CP_UTF8)
    , m_consolesCodepage(0)
  {
    m_hInput = ::GetStdHandle(STD_INPUT_HANDLE);
    checkHandle(true, "STD_INPUT_HANDLE");
    if (!setActiveInputCodepage()) {
      throw std::runtime_error("setActiveInputCodepage failed!");
    }
    m_hOutput = err ? ::GetStdHandle(STD_ERROR_HANDLE)
                    : ::GetStdHandle(STD_OUTPUT_HANDLE);
    checkHandle(false, err ? "STD_ERROR_HANDLE" : "STD_OUTPUT_HANDLE");
    if (!setActiveOutputCodepage()) {
      throw std::runtime_error("setActiveOutputCodepage failed!");
    }
    _setg();
    _setp();
  }

  ~BasicConsoleBuf() throw() { sync(); }

  bool activateCodepageChange()
  {
    return setActiveInputCodepage() && setActiveOutputCodepage();
  }

protected:
  virtual int sync()
  {
    bool success = true;
    if (m_hInput && m_isConsoleInput &&
        ::FlushConsoleInputBuffer(m_hInput) == 0) {
      success = false;
    }
    if (m_hOutput && !m_obuffer.empty()) {
      const std::wstring wbuffer = getBuffer(m_obuffer);
      if (m_isConsoleOutput) {
        DWORD charsWritten;
        success =
          ::WriteConsoleW(m_hOutput, wbuffer.c_str(), (DWORD)wbuffer.size(),
                          &charsWritten, NULL) == 0
          ? false
          : true;
      } else {
        DWORD bytesWritten;
        std::string buffer;
        success = encodeOutputBuffer(wbuffer, buffer);
        if (success) {
          success = ::WriteFile(m_hOutput, buffer.c_str(),
                                (DWORD)buffer.size(), &bytesWritten, NULL) == 0
            ? false
            : true;
        }
      }
    }
    m_ibuffer.clear();
    m_obuffer.clear();
    _setg();
    _setp();
    return success ? 0 : -1;
  }

  virtual int_type underflow()
  {
    if (this->gptr() >= this->egptr()) {
      if (!m_hInput) {
        _setg(true);
        return Traits::eof();
      }
      if (m_isConsoleInput) {
        // ReadConsole doesn't tell if there's more input available
        // don't support reading more characters than this
        wchar_t wbuffer[8192];
        DWORD charsRead;
        if (ReadConsoleW(m_hInput, wbuffer,
                         (sizeof(wbuffer) / sizeof(wbuffer[0])), &charsRead,
                         NULL) == 0 ||
            charsRead == 0) {
          _setg(true);
          return Traits::eof();
        }
        setBuffer(std::wstring(wbuffer, charsRead), m_ibuffer);
      } else {
        std::wstring wbuffer;
        std::string strbuffer;
        DWORD bytesRead;
        LARGE_INTEGER size;
        if (GetFileSizeEx(m_hInput, &size) == 0) {
          _setg(true);
          return Traits::eof();
        }
        char* buffer = new char[size.LowPart];
        while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, NULL) ==
               0) {
          if (GetLastError() == ERROR_MORE_DATA) {
            strbuffer += std::string(buffer, bytesRead);
            continue;
          }
          _setg(true);
          delete[] buffer;
          return Traits::eof();
        }
        if (bytesRead > 0) {
          strbuffer += std::string(buffer, bytesRead);
        }
        delete[] buffer;
        if (!decodeInputBuffer(strbuffer, wbuffer)) {
          _setg(true);
          return Traits::eof();
        }
        setBuffer(wbuffer, m_ibuffer);
      }
      _setg();
    }
    return Traits::to_int_type(*this->gptr());
  }

  virtual int_type overflow(int_type ch = Traits::eof())
  {
    if (!Traits::eq_int_type(ch, Traits::eof())) {
      char_type chr = Traits::to_char_type(ch);
      m_obuffer += chr;
      if ((flush_on_newline && Traits::eq(chr, '\n')) ||
          Traits::eq_int_type(ch, 0x00)) {
        sync();
      }
      return ch;
    }
    sync();
    return Traits::eof();
  }

public:
  bool flush_on_newline;
  UINT input_pipe_codepage;
  UINT output_pipe_codepage;
  UINT input_file_codepage;
  UINT output_file_codepage;

private:
  HANDLE m_hInput;
  HANDLE m_hOutput;
  std::basic_string<char_type> m_ibuffer;
  std::basic_string<char_type> m_obuffer;
  bool m_isConsoleInput;
  bool m_isConsoleOutput;
  UINT m_activeInputCodepage;
  UINT m_activeOutputCodepage;
  UINT m_consolesCodepage;
  void checkHandle(bool input, std::string handleName)
  {
    if ((input && m_hInput == INVALID_HANDLE_VALUE) ||
        (!input && m_hOutput == INVALID_HANDLE_VALUE)) {
      std::string errmsg =
        "GetStdHandle(" + handleName + ") returned INVALID_HANDLE_VALUE";
#  if __cplusplus >= 201103L
      throw std::system_error(::GetLastError(), std::system_category(),
                              errmsg);
#  else
      throw std::runtime_error(errmsg);
#  endif
    }
  }
  UINT getConsolesCodepage()
  {
    if (!m_consolesCodepage) {
      m_consolesCodepage = GetConsoleCP();
      if (!m_consolesCodepage) {
        m_consolesCodepage = GetACP();
      }
    }
    return m_consolesCodepage;
  }
  bool setActiveInputCodepage()
  {
    m_isConsoleInput = false;
    switch (GetFileType(m_hInput)) {
      case FILE_TYPE_DISK:
        m_activeInputCodepage = input_file_codepage;
        break;
      case FILE_TYPE_CHAR:
        // Check for actual console.
        DWORD consoleMode;
        m_isConsoleInput =
          GetConsoleMode(m_hInput, &consoleMode) == 0 ? false : true;
        if (m_isConsoleInput) {
          break;
        }
        @KWSYS_NAMESPACE@_FALLTHROUGH;
      case FILE_TYPE_PIPE:
        m_activeInputCodepage = input_pipe_codepage;
        break;
      default:
        return false;
    }
    if (!m_isConsoleInput && m_activeInputCodepage == 0) {
      m_activeInputCodepage = getConsolesCodepage();
    }
    return true;
  }
  bool setActiveOutputCodepage()
  {
    m_isConsoleOutput = false;
    switch (GetFileType(m_hOutput)) {
      case FILE_TYPE_DISK:
        m_activeOutputCodepage = output_file_codepage;
        break;
      case FILE_TYPE_CHAR:
        // Check for actual console.
        DWORD consoleMode;
        m_isConsoleOutput =
          GetConsoleMode(m_hOutput, &consoleMode) == 0 ? false : true;
        if (m_isConsoleOutput) {
          break;
        }
        @KWSYS_NAMESPACE@_FALLTHROUGH;
      case FILE_TYPE_PIPE:
        m_activeOutputCodepage = output_pipe_codepage;
        break;
      default:
        return false;
    }
    if (!m_isConsoleOutput && m_activeOutputCodepage == 0) {
      m_activeOutputCodepage = getConsolesCodepage();
    }
    return true;
  }
  void _setg(bool empty = false)
  {
    if (!empty) {
      this->setg((char_type*)m_ibuffer.data(), (char_type*)m_ibuffer.data(),
                 (char_type*)m_ibuffer.data() + m_ibuffer.size());
    } else {
      this->setg((char_type*)m_ibuffer.data(),
                 (char_type*)m_ibuffer.data() + m_ibuffer.size(),
                 (char_type*)m_ibuffer.data() + m_ibuffer.size());
    }
  }
  void _setp()
  {
    this->setp((char_type*)m_obuffer.data(),
               (char_type*)m_obuffer.data() + m_obuffer.size());
  }
  bool encodeOutputBuffer(const std::wstring wbuffer, std::string& buffer)
  {
    if (wbuffer.size() == 0) {
      buffer = std::string();
      return true;
    }
    const int length =
      WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(),
                          (int)wbuffer.size(), NULL, 0, NULL, NULL);
    char* buf = new char[length];
    const bool success =
      WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(),
                          (int)wbuffer.size(), buf, length, NULL, NULL) > 0
      ? true
      : false;
    buffer = std::string(buf, length);
    delete[] buf;
    return success;
  }
  bool decodeInputBuffer(const std::string buffer, std::wstring& wbuffer)
  {
    size_t length = buffer.length();
    if (length == 0) {
      wbuffer = std::wstring();
      return true;
    }
    int actualCodepage = m_activeInputCodepage;
    const char BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) };
    const char* data = buffer.data();
    const size_t BOMsize = sizeof(BOM_UTF8);
    if (length >= BOMsize && std::memcmp(data, BOM_UTF8, BOMsize) == 0) {
      // PowerShell uses UTF-8 with BOM for pipes
      actualCodepage = CP_UTF8;
      data += BOMsize;
      length -= BOMsize;
    }
    const size_t wlength = static_cast<size_t>(MultiByteToWideChar(
      actualCodepage, 0, data, static_cast<int>(length), NULL, 0));
    wchar_t* wbuf = new wchar_t[wlength];
    const bool success =
      MultiByteToWideChar(actualCodepage, 0, data, static_cast<int>(length),
                          wbuf, static_cast<int>(wlength)) > 0
      ? true
      : false;
    wbuffer = std::wstring(wbuf, wlength);
    delete[] wbuf;
    return success;
  }
  std::wstring getBuffer(const std::basic_string<char> buffer)
  {
    return Encoding::ToWide(buffer);
  }
  std::wstring getBuffer(const std::basic_string<wchar_t> buffer)
  {
    return buffer;
  }
  void setBuffer(const std::wstring wbuffer, std::basic_string<char>& target)
  {
    target = Encoding::ToNarrow(wbuffer);
  }
  void setBuffer(const std::wstring wbuffer,
                 std::basic_string<wchar_t>& target)
  {
    target = wbuffer;
  }

}; // BasicConsoleBuf class

typedef BasicConsoleBuf<char> ConsoleBuf;
typedef BasicConsoleBuf<wchar_t> WConsoleBuf;

#endif
} // KWSYS_NAMESPACE

#endif
