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

#include "cmProcessOutput.h"

#if defined(_WIN32)
#  include <cm/memory>

#  include <windows.h>

unsigned int cmProcessOutput::defaultCodepage =
  KWSYS_ENCODING_DEFAULT_CODEPAGE;
#endif

cm::optional<cmProcessOutput::Encoding> cmProcessOutput::FindEncoding(
  std::string const& name)
{
  cm::optional<Encoding> encoding;
  if ((name == "UTF8") || (name == "UTF-8")) {
    encoding = UTF8;
  } else if (name == "NONE") {
    encoding = None;
  } else if (name == "ANSI") {
    encoding = ANSI;
  } else if (name == "AUTO") {
    encoding = Auto;
  } else if (name == "OEM") {
    encoding = OEM;
  }
  return encoding;
}

cmProcessOutput::cmProcessOutput(Encoding encoding, unsigned int maxSize)
{
#if defined(_WIN32)
  codepage = 0;
  bufferSize = maxSize;
  if (encoding == None) {
    codepage = defaultCodepage;
  } else if (encoding == Auto) {
    codepage = GetConsoleCP();
  } else if (encoding == UTF8) {
    codepage = CP_UTF8;
  } else if (encoding == OEM) {
    codepage = GetOEMCP();
  }
  if (!codepage || encoding == ANSI) {
    codepage = GetACP();
  }
#else
  static_cast<void>(encoding);
  static_cast<void>(maxSize);
#endif
}

bool cmProcessOutput::DecodeText(std::string raw, std::string& decoded,
                                 size_t id)
{
#if !defined(_WIN32)
  static_cast<void>(id);
  decoded.swap(raw);
  return true;
#else
  bool success = true;
  decoded = raw;
  if (id > 0) {
    if (rawparts.size() < id) {
      rawparts.reserve(id);
      while (rawparts.size() < id)
        rawparts.push_back(std::string());
    }
    raw = rawparts[id - 1] + raw;
    rawparts[id - 1].clear();
    decoded = raw;
  }
  if (raw.size() > 0 && codepage != defaultCodepage) {
    success = false;
    CPINFOEXW cpinfo;
    if (id > 0 && bufferSize > 0 && raw.size() == bufferSize &&
        GetCPInfoExW(codepage, 0, &cpinfo) == 1 && cpinfo.MaxCharSize > 1) {
      if (cpinfo.MaxCharSize == 2 && cpinfo.LeadByte[0] != 0) {
        LPSTR prevChar =
          CharPrevExA(codepage, raw.c_str(), raw.c_str() + raw.size(), 0);
        bool isLeadByte =
          (*(prevChar + 1) == 0) && IsDBCSLeadByteEx(codepage, *prevChar);
        if (isLeadByte) {
          rawparts[id - 1] += *(raw.end() - 1);
          raw.resize(raw.size() - 1);
        }
        success = DoDecodeText(raw, decoded, nullptr);
      } else {
        bool restoreDecoded = false;
        std::string firstDecoded = decoded;
        wchar_t lastChar = 0;
        for (UINT i = 0; i < cpinfo.MaxCharSize; i++) {
          success = DoDecodeText(raw, decoded, &lastChar);
          if (success && lastChar != 0) {
            if (i == 0) {
              firstDecoded = decoded;
            }
            if (lastChar == cpinfo.UnicodeDefaultChar) {
              restoreDecoded = true;
              rawparts[id - 1] = *(raw.end() - 1) + rawparts[id - 1];
              raw.resize(raw.size() - 1);
            } else {
              restoreDecoded = false;
              break;
            }
          } else {
            break;
          }
        }
        if (restoreDecoded) {
          decoded = firstDecoded;
          rawparts[id - 1].clear();
        }
      }
    } else {
      success = DoDecodeText(raw, decoded, nullptr);
    }
  }
  return success;
#endif
}

bool cmProcessOutput::DecodeText(const char* data, size_t length,
                                 std::string& decoded, size_t id)
{
  return this->DecodeText(std::string(data, length), decoded, id);
}

bool cmProcessOutput::DecodeText(std::vector<char> raw,
                                 std::vector<char>& decoded, size_t id)
{
  std::string str;
  const bool success =
    this->DecodeText(std::string(raw.begin(), raw.end()), str, id);
  decoded.assign(str.begin(), str.end());
  return success;
}

#if defined(_WIN32)
bool cmProcessOutput::DoDecodeText(std::string raw, std::string& decoded,
                                   wchar_t* lastChar)
{
  bool success = false;
  const int wlength =
    MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), nullptr, 0);
  auto wdata = cm::make_unique<wchar_t[]>(wlength);
  int r = MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()),
                              wdata.get(), wlength);
  if (r > 0) {
    if (lastChar) {
      *lastChar = 0;
      if ((wlength >= 2 && wdata[wlength - 2] != wdata[wlength - 1]) ||
          wlength >= 1) {
        *lastChar = wdata[wlength - 1];
      }
    }
    int length = WideCharToMultiByte(defaultCodepage, 0, wdata.get(), wlength,
                                     nullptr, 0, nullptr, nullptr);
    auto data = cm::make_unique<char[]>(length);
    r = WideCharToMultiByte(defaultCodepage, 0, wdata.get(), wlength,
                            data.get(), length, nullptr, nullptr);
    if (r > 0) {
      decoded = std::string(data.get(), length);
      success = true;
    }
  }
  return success;
}
#endif
