/* 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,
                     NULL, errorCode, 0, (LPWSTR)&message, 0, NULL)) {
    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(NULL, 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(NULL,            // No module name (use command line)
                   cmd,             // Command line
                   NULL,            // Process handle not inheritable
                   NULL,            // Thread handle not inheritable
                   bInheritHandles, // Set handle inheritance
                   dwCreationFlags,
                   NULL,         // Use parent's environment block
                   NULL,         // 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 = NULL;
  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 = NULL;

  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,
                NULL); // 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,
                   NULL) ||
        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, NULL) ||
            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, NULL)) ||
            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,
                        NULL) ||
              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), NULL, NULL)) == 0) {
      throw std::runtime_error("WideCharToMultiByte failed!");
    }
    buffer[length - 1] = '\n';
    if (!WriteFile(inFile, buffer, length, &bytesWritten, NULL) ||
        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, NULL) ||
            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, NULL) ||
              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", NULL, NULL,
                           (LPBYTE)&FontFamily, &dwordSize) == ERROR_SUCCESS) {
        if (FontFamily != TestFontFamily) {
          RegQueryValueExW(hConsoleKey, L"FaceName", NULL, NULL,
                           (LPBYTE)FaceName, &FaceNameSize);
          RegQueryValueExW(hConsoleKey, L"FontSize", NULL, NULL,
                           (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 = NULL;
    hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE,
                      FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes,
                      OPEN_EXISTING, 0, NULL);
    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, NULL);
    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(NULL, NULL, NULL)) {
    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(NULL,
                                  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(NULL, 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;
}
