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

// Ignore Windows version levels defined by command-line flags.  This
// source needs access to all APIs available on the host in order for
// the test to run properly.  The test binary is not installed anyway.
#undef _WIN32_WINNT
#undef NTDDI_VERSION

#include KWSYS_HEADER(Encoding.hxx)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
#  include "Encoding.hxx.in"
#endif

#if defined(_WIN32)

#  include <algorithm>
#  include <iomanip>
#  include <iostream>
#  include <stdexcept>
#  include <string.h>
#  include <wchar.h>
#  include <windows.h>

#  include "testConsoleBuf.hxx"

#  if defined(_MSC_VER) && _MSC_VER >= 1800
#    define KWSYS_WINDOWS_DEPRECATED_GetVersion
#  endif
// يونيكود
static const WCHAR UnicodeInputTestString[] =
  L"\u064A\u0648\u0646\u064A\u0643\u0648\u062F!";
static UINT TestCodepage = KWSYS_ENCODING_DEFAULT_CODEPAGE;

static const DWORD waitTimeout = 10 * 1000;
static STARTUPINFO startupInfo;
static PROCESS_INFORMATION processInfo;
static HANDLE beforeInputEvent;
static HANDLE afterOutputEvent;
static std::string encodedInputTestString;
static std::string encodedTestString;

static void displayError(DWORD errorCode)
{
  std::cerr.setf(std::ios::hex, std::ios::basefield);
  std::cerr << "Failed with error: 0x" << errorCode << "!" << std::endl;
  LPWSTR message;
  if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                       FORMAT_MESSAGE_FROM_SYSTEM,
                     nullptr, errorCode, 0, (LPWSTR)&message, 0, nullptr)) {
    std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message)
              << std::endl;
    HeapFree(GetProcessHeap(), 0, message);
  } else {
    std::cerr << "FormatMessage() failed with error: 0x" << GetLastError()
              << "!" << std::endl;
  }
  std::cerr.unsetf(std::ios::hex);
}

std::basic_streambuf<char>* errstream(const char* unused)
{
  static_cast<void>(unused);
  return std::cerr.rdbuf();
}

std::basic_streambuf<wchar_t>* errstream(const wchar_t* unused)
{
  static_cast<void>(unused);
  return std::wcerr.rdbuf();
}

template <typename T>
static void dumpBuffers(const T* expected, const T* received, size_t size)
{
  std::basic_ostream<T> err(errstream(expected));
  err << "Expected output: '" << std::basic_string<T>(expected, size) << "'"
      << std::endl;
  if (err.fail()) {
    err.clear();
    err << "--- Error while outputting ---" << std::endl;
  }
  err << "Received output: '" << std::basic_string<T>(received, size) << "'"
      << std::endl;
  if (err.fail()) {
    err.clear();
    err << "--- Error while outputting ---" << std::endl;
  }
  std::cerr << "Expected output | Received output" << std::endl;
  for (size_t i = 0; i < size; i++) {
    std::cerr << std::setbase(16) << std::setfill('0') << "     "
              << "0x" << std::setw(8) << static_cast<unsigned int>(expected[i])
              << " | "
              << "0x" << std::setw(8)
              << static_cast<unsigned int>(received[i]);
    if (static_cast<unsigned int>(expected[i]) !=
        static_cast<unsigned int>(received[i])) {
      std::cerr << "   MISMATCH!";
    }
    std::cerr << std::endl;
  }
  std::cerr << std::endl;
}

static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr)
{
  BOOL bInheritHandles = FALSE;
  DWORD dwCreationFlags = 0;
  memset(&processInfo, 0, sizeof(processInfo));
  memset(&startupInfo, 0, sizeof(startupInfo));
  startupInfo.cb = sizeof(startupInfo);
  startupInfo.dwFlags = STARTF_USESHOWWINDOW;
  startupInfo.wShowWindow = SW_HIDE;
  if (hIn || hOut || hErr) {
    startupInfo.dwFlags |= STARTF_USESTDHANDLES;
    startupInfo.hStdInput = hIn;
    startupInfo.hStdOutput = hOut;
    startupInfo.hStdError = hErr;
    bInheritHandles = TRUE;
  }

  WCHAR cmd[MAX_PATH];
  if (GetModuleFileNameW(nullptr, cmd, MAX_PATH) == 0) {
    std::cerr << "GetModuleFileName failed!" << std::endl;
    return false;
  }
  WCHAR* p = cmd + wcslen(cmd);
  while (p > cmd && *p != L'\\')
    p--;
  *(p + 1) = 0;
  wcscat(cmd, cmdConsoleBufChild);
  wcscat(cmd, L".exe");

  bool success =
    CreateProcessW(nullptr,         // No module name (use command line)
                   cmd,             // Command line
                   nullptr,         // Process handle not inheritable
                   nullptr,         // Thread handle not inheritable
                   bInheritHandles, // Set handle inheritance
                   dwCreationFlags,
                   nullptr,      // Use parent's environment block
                   nullptr,      // Use parent's starting directory
                   &startupInfo, // Pointer to STARTUPINFO structure
                   &processInfo) !=
    0; // Pointer to PROCESS_INFORMATION structure
  if (!success) {
    DWORD lastError = GetLastError();
    std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) << ")"
              << std::endl;
    displayError(lastError);
  }
  return success;
}

static void finishProcess(bool success)
{
  if (success) {
    success =
      WaitForSingleObject(processInfo.hProcess, waitTimeout) == WAIT_OBJECT_0;
  };
  if (!success) {
    TerminateProcess(processInfo.hProcess, 1);
  }
  CloseHandle(processInfo.hProcess);
  CloseHandle(processInfo.hThread);
}

static bool createPipe(PHANDLE readPipe, PHANDLE writePipe)
{
  SECURITY_ATTRIBUTES securityAttributes;
  securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  securityAttributes.bInheritHandle = TRUE;
  securityAttributes.lpSecurityDescriptor = nullptr;
  return CreatePipe(readPipe, writePipe, &securityAttributes, 0) == 0 ? false
                                                                      : true;
}

static void finishPipe(HANDLE readPipe, HANDLE writePipe)
{
  if (readPipe != INVALID_HANDLE_VALUE) {
    CloseHandle(readPipe);
  }
  if (writePipe != INVALID_HANDLE_VALUE) {
    CloseHandle(writePipe);
  }
}

static HANDLE createFile(LPCWSTR fileName)
{
  SECURITY_ATTRIBUTES securityAttributes;
  securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  securityAttributes.bInheritHandle = TRUE;
  securityAttributes.lpSecurityDescriptor = nullptr;

  HANDLE file =
    CreateFileW(fileName, GENERIC_READ | GENERIC_WRITE,
                0, // do not share
                &securityAttributes,
                CREATE_ALWAYS, // overwrite existing
                FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
                nullptr); // no template
  if (file == INVALID_HANDLE_VALUE) {
    DWORD lastError = GetLastError();
    std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")"
              << std::endl;
    displayError(lastError);
  }
  return file;
}

static void finishFile(HANDLE file)
{
  if (file != INVALID_HANDLE_VALUE) {
    CloseHandle(file);
  }
}

#  ifndef MAPVK_VK_TO_VSC
#    define MAPVK_VK_TO_VSC (0)
#  endif

static void writeInputKeyEvent(INPUT_RECORD inputBuffer[], WCHAR chr)
{
  inputBuffer[0].EventType = KEY_EVENT;
  inputBuffer[0].Event.KeyEvent.bKeyDown = TRUE;
  inputBuffer[0].Event.KeyEvent.wRepeatCount = 1;
  SHORT keyCode = VkKeyScanW(chr);
  if (keyCode == -1) {
    // Character can't be entered with current keyboard layout
    // Just set any, it doesn't really matter
    keyCode = 'K';
  }
  inputBuffer[0].Event.KeyEvent.wVirtualKeyCode = LOBYTE(keyCode);
  inputBuffer[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(
    inputBuffer[0].Event.KeyEvent.wVirtualKeyCode, MAPVK_VK_TO_VSC);
  inputBuffer[0].Event.KeyEvent.uChar.UnicodeChar = chr;
  inputBuffer[0].Event.KeyEvent.dwControlKeyState = 0;
  if ((HIBYTE(keyCode) & 1) == 1) {
    inputBuffer[0].Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
  }
  if ((HIBYTE(keyCode) & 2) == 2) {
    inputBuffer[0].Event.KeyEvent.dwControlKeyState |= RIGHT_CTRL_PRESSED;
  }
  if ((HIBYTE(keyCode) & 4) == 4) {
    inputBuffer[0].Event.KeyEvent.dwControlKeyState |= RIGHT_ALT_PRESSED;
  }
  inputBuffer[1].EventType = inputBuffer[0].EventType;
  inputBuffer[1].Event.KeyEvent.bKeyDown = FALSE;
  inputBuffer[1].Event.KeyEvent.wRepeatCount = 1;
  inputBuffer[1].Event.KeyEvent.wVirtualKeyCode =
    inputBuffer[0].Event.KeyEvent.wVirtualKeyCode;
  inputBuffer[1].Event.KeyEvent.wVirtualScanCode =
    inputBuffer[0].Event.KeyEvent.wVirtualScanCode;
  inputBuffer[1].Event.KeyEvent.uChar.UnicodeChar =
    inputBuffer[0].Event.KeyEvent.uChar.UnicodeChar;
  inputBuffer[1].Event.KeyEvent.dwControlKeyState = 0;
}

static int testPipe()
{
  int didFail = 1;
  HANDLE inPipeRead = INVALID_HANDLE_VALUE;
  HANDLE inPipeWrite = INVALID_HANDLE_VALUE;
  HANDLE outPipeRead = INVALID_HANDLE_VALUE;
  HANDLE outPipeWrite = INVALID_HANDLE_VALUE;
  HANDLE errPipeRead = INVALID_HANDLE_VALUE;
  HANDLE errPipeWrite = INVALID_HANDLE_VALUE;
  UINT currentCodepage = GetConsoleCP();
  char buffer[200];
  char buffer2[200];
  try {
    if (!createPipe(&inPipeRead, &inPipeWrite) ||
        !createPipe(&outPipeRead, &outPipeWrite) ||
        !createPipe(&errPipeRead, &errPipeWrite)) {
      throw std::runtime_error("createFile failed!");
    }
    if (TestCodepage == CP_ACP) {
      TestCodepage = GetACP();
    }
    if (!SetConsoleCP(TestCodepage)) {
      throw std::runtime_error("SetConsoleCP failed!");
    }

    DWORD bytesWritten = 0;
    if (!WriteFile(inPipeWrite, encodedInputTestString.c_str(),
                   (DWORD)encodedInputTestString.size(), &bytesWritten,
                   nullptr) ||
        bytesWritten == 0) {
      throw std::runtime_error("WriteFile failed!");
    }

    if (createProcess(inPipeRead, outPipeWrite, errPipeWrite)) {
      try {
        DWORD status;
        if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) !=
            WAIT_OBJECT_0) {
          std::cerr.setf(std::ios::hex, std::ios::basefield);
          std::cerr << "WaitForSingleObject returned unexpected status 0x"
                    << status << std::endl;
          std::cerr.unsetf(std::ios::hex);
          throw std::runtime_error("WaitForSingleObject failed!");
        }
        DWORD bytesRead = 0;
        if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead,
                      nullptr) ||
            bytesRead == 0) {
          throw std::runtime_error("ReadFile#1 failed!");
        }
        buffer[bytesRead] = 0;
        if ((bytesRead <
               encodedTestString.size() + 1 + encodedInputTestString.size() &&
             !ReadFile(outPipeRead, buffer + bytesRead,
                       sizeof(buffer) - bytesRead, &bytesRead, nullptr)) ||
            bytesRead == 0) {
          throw std::runtime_error("ReadFile#2 failed!");
        }
        if (memcmp(buffer, encodedTestString.c_str(),
                   encodedTestString.size()) == 0 &&
            memcmp(buffer + encodedTestString.size() + 1,
                   encodedInputTestString.c_str(),
                   encodedInputTestString.size()) == 0) {
          bytesRead = 0;
          if (!ReadFile(errPipeRead, buffer2, sizeof(buffer2), &bytesRead,
                        nullptr) ||
              bytesRead == 0) {
            throw std::runtime_error("ReadFile#3 failed!");
          }
          buffer2[bytesRead] = 0;
          didFail = encodedTestString.compare(0, std::string::npos, buffer2,
                                              encodedTestString.size()) == 0
            ? 0
            : 1;
        }
        if (didFail != 0) {
          std::cerr << "Pipe's output didn't match expected output!"
                    << std::endl;
          dumpBuffers<char>(encodedTestString.c_str(), buffer,
                            encodedTestString.size());
          dumpBuffers<char>(encodedInputTestString.c_str(),
                            buffer + encodedTestString.size() + 1,
                            encodedInputTestString.size());
          dumpBuffers<char>(encodedTestString.c_str(), buffer2,
                            encodedTestString.size());
        }
      } catch (const std::runtime_error& ex) {
        DWORD lastError = GetLastError();
        std::cerr << "In function testPipe, line " << __LINE__ << ": "
                  << ex.what() << std::endl;
        displayError(lastError);
      }
      finishProcess(didFail == 0);
    }
  } catch (const std::runtime_error& ex) {
    DWORD lastError = GetLastError();
    std::cerr << "In function testPipe, line " << __LINE__ << ": " << ex.what()
              << std::endl;
    displayError(lastError);
  }
  finishPipe(inPipeRead, inPipeWrite);
  finishPipe(outPipeRead, outPipeWrite);
  finishPipe(errPipeRead, errPipeWrite);
  SetConsoleCP(currentCodepage);
  return didFail;
}

static int testFile()
{
  int didFail = 1;
  HANDLE inFile = INVALID_HANDLE_VALUE;
  HANDLE outFile = INVALID_HANDLE_VALUE;
  HANDLE errFile = INVALID_HANDLE_VALUE;
  try {
    if ((inFile = createFile(L"stdinFile.txt")) == INVALID_HANDLE_VALUE ||
        (outFile = createFile(L"stdoutFile.txt")) == INVALID_HANDLE_VALUE ||
        (errFile = createFile(L"stderrFile.txt")) == INVALID_HANDLE_VALUE) {
      throw std::runtime_error("createFile failed!");
    }
    DWORD bytesWritten = 0;
    char buffer[200];
    char buffer2[200];

    int length;
    if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString,
                                      -1, buffer, sizeof(buffer), nullptr,
                                      nullptr)) == 0) {
      throw std::runtime_error("WideCharToMultiByte failed!");
    }
    buffer[length - 1] = '\n';
    if (!WriteFile(inFile, buffer, length, &bytesWritten, nullptr) ||
        bytesWritten == 0) {
      throw std::runtime_error("WriteFile failed!");
    }
    if (SetFilePointer(inFile, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
      throw std::runtime_error("SetFilePointer failed!");
    }

    if (createProcess(inFile, outFile, errFile)) {
      DWORD bytesRead = 0;
      try {
        DWORD status;
        if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) !=
            WAIT_OBJECT_0) {
          std::cerr.setf(std::ios::hex, std::ios::basefield);
          std::cerr << "WaitForSingleObject returned unexpected status 0x"
                    << status << std::endl;
          std::cerr.unsetf(std::ios::hex);
          throw std::runtime_error("WaitForSingleObject failed!");
        }
        if (SetFilePointer(outFile, 0, 0, FILE_BEGIN) ==
            INVALID_SET_FILE_POINTER) {
          throw std::runtime_error("SetFilePointer#1 failed!");
        }
        if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, nullptr) ||
            bytesRead == 0) {
          throw std::runtime_error("ReadFile#1 failed!");
        }
        buffer[bytesRead] = 0;
        if (memcmp(buffer, encodedTestString.c_str(),
                   encodedTestString.size()) == 0 &&
            memcmp(buffer + encodedTestString.size() + 1,
                   encodedInputTestString.c_str(),
                   encodedInputTestString.size()) == 0) {
          bytesRead = 0;
          if (SetFilePointer(errFile, 0, 0, FILE_BEGIN) ==
              INVALID_SET_FILE_POINTER) {
            throw std::runtime_error("SetFilePointer#2 failed!");
          }

          if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead,
                        nullptr) ||
              bytesRead == 0) {
            throw std::runtime_error("ReadFile#2 failed!");
          }
          buffer2[bytesRead] = 0;
          didFail = encodedTestString.compare(0, std::string::npos, buffer2,
                                              encodedTestString.size()) == 0
            ? 0
            : 1;
        }
        if (didFail != 0) {
          std::cerr << "File's output didn't match expected output!"
                    << std::endl;
          dumpBuffers<char>(encodedTestString.c_str(), buffer,
                            encodedTestString.size());
          dumpBuffers<char>(encodedInputTestString.c_str(),
                            buffer + encodedTestString.size() + 1,
                            encodedInputTestString.size());
          dumpBuffers<char>(encodedTestString.c_str(), buffer2,
                            encodedTestString.size());
        }
      } catch (const std::runtime_error& ex) {
        DWORD lastError = GetLastError();
        std::cerr << "In function testFile, line " << __LINE__ << ": "
                  << ex.what() << std::endl;
        displayError(lastError);
      }
      finishProcess(didFail == 0);
    }
  } catch (const std::runtime_error& ex) {
    DWORD lastError = GetLastError();
    std::cerr << "In function testFile, line " << __LINE__ << ": " << ex.what()
              << std::endl;
    displayError(lastError);
  }
  finishFile(inFile);
  finishFile(outFile);
  finishFile(errFile);
  return didFail;
}

#  ifndef _WIN32_WINNT_VISTA
#    define _WIN32_WINNT_VISTA 0x0600
#  endif

static int testConsole()
{
  int didFail = 1;
  HANDLE parentIn = GetStdHandle(STD_INPUT_HANDLE);
  HANDLE parentOut = GetStdHandle(STD_OUTPUT_HANDLE);
  HANDLE parentErr = GetStdHandle(STD_ERROR_HANDLE);
  HANDLE hIn = parentIn;
  HANDLE hOut = parentOut;
  DWORD consoleMode;
  bool newConsole = false;
  bool forceNewConsole = false;
  bool restoreConsole = false;
  LPCWSTR TestFaceName = L"Lucida Console";
  const DWORD TestFontFamily = 0x00000036;
  const DWORD TestFontSize = 0x000c0000;
  HKEY hConsoleKey;
  WCHAR FaceName[200];
  FaceName[0] = 0;
  DWORD FaceNameSize = sizeof(FaceName);
  DWORD FontFamily = TestFontFamily;
  DWORD FontSize = TestFontSize;
#  ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion
#    pragma warning(push)
#    ifdef __INTEL_COMPILER
#      pragma warning(disable : 1478)
#    elif defined __clang__
#      pragma clang diagnostic push
#      pragma clang diagnostic ignored "-Wdeprecated-declarations"
#    else
#      pragma warning(disable : 4996)
#    endif
#  endif
  const bool isVistaOrGreater =
    LOBYTE(LOWORD(GetVersion())) >= HIBYTE(_WIN32_WINNT_VISTA);
#  ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion
#    ifdef __clang__
#      pragma clang diagnostic pop
#    else
#      pragma warning(pop)
#    endif
#  endif
  if (!isVistaOrGreater) {
    if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ | KEY_WRITE,
                      &hConsoleKey) == ERROR_SUCCESS) {
      DWORD dwordSize = sizeof(DWORD);
      if (RegQueryValueExW(hConsoleKey, L"FontFamily", nullptr, nullptr,
                           (LPBYTE)&FontFamily, &dwordSize) == ERROR_SUCCESS) {
        if (FontFamily != TestFontFamily) {
          RegQueryValueExW(hConsoleKey, L"FaceName", nullptr, nullptr,
                           (LPBYTE)FaceName, &FaceNameSize);
          RegQueryValueExW(hConsoleKey, L"FontSize", nullptr, nullptr,
                           (LPBYTE)&FontSize, &dwordSize);

          RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
                         (BYTE*)&TestFontFamily, sizeof(TestFontFamily));
          RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ,
                         (BYTE*)TestFaceName,
                         (DWORD)((wcslen(TestFaceName) + 1) * sizeof(WCHAR)));
          RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD,
                         (BYTE*)&TestFontSize, sizeof(TestFontSize));

          restoreConsole = true;
          forceNewConsole = true;
        }
      } else {
        std::cerr << "RegGetValueW(FontFamily) failed!" << std::endl;
      }
      RegCloseKey(hConsoleKey);
    } else {
      std::cerr << "RegOpenKeyExW(HKEY_CURRENT_USER\\Console) failed!"
                << std::endl;
    }
  }
  if (forceNewConsole || GetConsoleMode(parentOut, &consoleMode) == 0) {
    // Not a real console, let's create new one.
    FreeConsole();
    if (!AllocConsole()) {
      std::cerr << "AllocConsole failed!" << std::endl;
      return didFail;
    }
    SECURITY_ATTRIBUTES securityAttributes;
    securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
    securityAttributes.bInheritHandle = TRUE;
    securityAttributes.lpSecurityDescriptor = nullptr;
    hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE,
                      FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes,
                      OPEN_EXISTING, 0, nullptr);
    if (hIn == INVALID_HANDLE_VALUE) {
      DWORD lastError = GetLastError();
      std::cerr << "CreateFile(CONIN$)" << std::endl;
      displayError(lastError);
    }
    hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE,
                       FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes,
                       OPEN_EXISTING, 0, nullptr);
    if (hOut == INVALID_HANDLE_VALUE) {
      DWORD lastError = GetLastError();
      std::cerr << "CreateFile(CONOUT$)" << std::endl;
      displayError(lastError);
    }
    SetStdHandle(STD_INPUT_HANDLE, hIn);
    SetStdHandle(STD_OUTPUT_HANDLE, hOut);
    SetStdHandle(STD_ERROR_HANDLE, hOut);
    newConsole = true;
  }

#  if _WIN32_WINNT >= _WIN32_WINNT_VISTA
  if (isVistaOrGreater) {
    CONSOLE_FONT_INFOEX consoleFont;
    memset(&consoleFont, 0, sizeof(consoleFont));
    consoleFont.cbSize = sizeof(consoleFont);
    HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
    typedef BOOL(WINAPI * GetCurrentConsoleFontExFunc)(
      HANDLE hConsoleOutput, BOOL bMaximumWindow,
      PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
    typedef BOOL(WINAPI * SetCurrentConsoleFontExFunc)(
      HANDLE hConsoleOutput, BOOL bMaximumWindow,
      PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
    GetCurrentConsoleFontExFunc getConsoleFont =
      (GetCurrentConsoleFontExFunc)GetProcAddress(kernel32,
                                                  "GetCurrentConsoleFontEx");
    SetCurrentConsoleFontExFunc setConsoleFont =
      (SetCurrentConsoleFontExFunc)GetProcAddress(kernel32,
                                                  "SetCurrentConsoleFontEx");
    if (getConsoleFont(hOut, FALSE, &consoleFont)) {
      if (consoleFont.FontFamily != TestFontFamily) {
        consoleFont.FontFamily = TestFontFamily;
        wcscpy(consoleFont.FaceName, TestFaceName);
        if (!setConsoleFont(hOut, FALSE, &consoleFont)) {
          std::cerr << "SetCurrentConsoleFontEx failed!" << std::endl;
        }
      }
    } else {
      std::cerr << "GetCurrentConsoleFontEx failed!" << std::endl;
    }
  } else {
#  endif
    if (restoreConsole &&
        RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_WRITE,
                      &hConsoleKey) == ERROR_SUCCESS) {
      RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
                     (BYTE*)&FontFamily, sizeof(FontFamily));
      if (FaceName[0] != 0) {
        RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ, (BYTE*)FaceName,
                       FaceNameSize);
      } else {
        RegDeleteValueW(hConsoleKey, L"FaceName");
      }
      RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD, (BYTE*)&FontSize,
                     sizeof(FontSize));
      RegCloseKey(hConsoleKey);
    }
#  if _WIN32_WINNT >= _WIN32_WINNT_VISTA
  }
#  endif

  if (createProcess(nullptr, nullptr, nullptr)) {
    try {
      DWORD status;
      if ((status = WaitForSingleObject(beforeInputEvent, waitTimeout)) !=
          WAIT_OBJECT_0) {
        std::cerr.setf(std::ios::hex, std::ios::basefield);
        std::cerr << "WaitForSingleObject returned unexpected status 0x"
                  << status << std::endl;
        std::cerr.unsetf(std::ios::hex);
        throw std::runtime_error("WaitForSingleObject#1 failed!");
      }
      INPUT_RECORD inputBuffer[(sizeof(UnicodeInputTestString) /
                                sizeof(UnicodeInputTestString[0])) *
                               2];
      memset(&inputBuffer, 0, sizeof(inputBuffer));
      unsigned int i;
      for (i = 0; i < (sizeof(UnicodeInputTestString) /
                         sizeof(UnicodeInputTestString[0]) -
                       1);
           i++) {
        writeInputKeyEvent(&inputBuffer[i * 2], UnicodeInputTestString[i]);
      }
      writeInputKeyEvent(&inputBuffer[i * 2], VK_RETURN);
      DWORD eventsWritten = 0;
      // We need to wait a bit before writing to console so child process have
      // started waiting for input on stdin.
      Sleep(300);
      if (!WriteConsoleInputW(hIn, inputBuffer,
                              sizeof(inputBuffer) / sizeof(inputBuffer[0]),
                              &eventsWritten) ||
          eventsWritten == 0) {
        throw std::runtime_error("WriteConsoleInput failed!");
      }
      if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) !=
          WAIT_OBJECT_0) {
        std::cerr.setf(std::ios::hex, std::ios::basefield);
        std::cerr << "WaitForSingleObject returned unexpected status 0x"
                  << status << std::endl;
        std::cerr.unsetf(std::ios::hex);
        throw std::runtime_error("WaitForSingleObject#2 failed!");
      }
      CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
      if (!GetConsoleScreenBufferInfo(hOut, &screenBufferInfo)) {
        throw std::runtime_error("GetConsoleScreenBufferInfo failed!");
      }

      COORD coord;
      DWORD charsRead = 0;
      coord.X = 0;
      coord.Y = screenBufferInfo.dwCursorPosition.Y - 4;
      WCHAR* outputBuffer = new WCHAR[screenBufferInfo.dwSize.X * 4];
      if (!ReadConsoleOutputCharacterW(hOut, outputBuffer,
                                       screenBufferInfo.dwSize.X * 4, coord,
                                       &charsRead) ||
          charsRead == 0) {
        delete[] outputBuffer;
        throw std::runtime_error("ReadConsoleOutputCharacter failed!");
      }
      std::wstring wideTestString = kwsys::Encoding::ToWide(encodedTestString);
      std::replace(wideTestString.begin(), wideTestString.end(), '\0', ' ');
      std::wstring wideInputTestString =
        kwsys::Encoding::ToWide(encodedInputTestString);
      if (memcmp(outputBuffer, wideTestString.c_str(),
                 wideTestString.size() * sizeof(wchar_t)) == 0 &&
          memcmp(outputBuffer + screenBufferInfo.dwSize.X * 1,
                 wideTestString.c_str(),
                 wideTestString.size() * sizeof(wchar_t)) == 0 &&
          memcmp(outputBuffer + screenBufferInfo.dwSize.X * 2,
                 UnicodeInputTestString,
                 sizeof(UnicodeInputTestString) - sizeof(WCHAR)) == 0 &&
          memcmp(outputBuffer + screenBufferInfo.dwSize.X * 3,
                 wideInputTestString.c_str(),
                 (wideInputTestString.size() - 1) * sizeof(wchar_t)) == 0) {
        didFail = 0;
      } else {
        std::cerr << "Console's output didn't match expected output!"
                  << std::endl;
        dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer,
                             wideTestString.size());
        dumpBuffers<wchar_t>(wideTestString.c_str(),
                             outputBuffer + screenBufferInfo.dwSize.X * 1,
                             wideTestString.size());
        dumpBuffers<wchar_t>(
          UnicodeInputTestString, outputBuffer + screenBufferInfo.dwSize.X * 2,
          (sizeof(UnicodeInputTestString) - 1) / sizeof(WCHAR));
        dumpBuffers<wchar_t>(wideInputTestString.c_str(),
                             outputBuffer + screenBufferInfo.dwSize.X * 3,
                             wideInputTestString.size() - 1);
      }
      delete[] outputBuffer;
    } catch (const std::runtime_error& ex) {
      DWORD lastError = GetLastError();
      std::cerr << "In function testConsole, line " << __LINE__ << ": "
                << ex.what() << std::endl;
      displayError(lastError);
    }
    finishProcess(didFail == 0);
  }
  if (newConsole) {
    SetStdHandle(STD_INPUT_HANDLE, parentIn);
    SetStdHandle(STD_OUTPUT_HANDLE, parentOut);
    SetStdHandle(STD_ERROR_HANDLE, parentErr);
    CloseHandle(hIn);
    CloseHandle(hOut);
    FreeConsole();
  }
  return didFail;
}

#endif

int testConsoleBuf(int, char* [])
{
  int ret = 0;

#if defined(_WIN32)
  beforeInputEvent = CreateEventW(nullptr,
                                  FALSE, // auto-reset event
                                  FALSE, // initial state is nonsignaled
                                  BeforeInputEventName); // object name
  if (!beforeInputEvent) {
    std::cerr << "CreateEvent#1 failed " << GetLastError() << std::endl;
    return 1;
  }

  afterOutputEvent = CreateEventW(nullptr, FALSE, FALSE, AfterOutputEventName);
  if (!afterOutputEvent) {
    std::cerr << "CreateEvent#2 failed " << GetLastError() << std::endl;
    return 1;
  }

  encodedTestString = kwsys::Encoding::ToNarrow(std::wstring(
    UnicodeTestString, sizeof(UnicodeTestString) / sizeof(wchar_t) - 1));
  encodedInputTestString = kwsys::Encoding::ToNarrow(
    std::wstring(UnicodeInputTestString,
                 sizeof(UnicodeInputTestString) / sizeof(wchar_t) - 1));
  encodedInputTestString += "\n";

  ret |= testPipe();
  ret |= testFile();
  ret |= testConsole();

  CloseHandle(beforeInputEvent);
  CloseHandle(afterOutputEvent);
#endif

  return ret;
}
