// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(DART_HOST_OS_WINDOWS)

#include "bin/stdio.h"

// These are not always defined in the header files. See:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
#endif

#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif

namespace dart {
namespace bin {

bool Stdin::ReadByte(intptr_t fd, int* byte) {
  HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
  uint8_t buffer[1];
  DWORD read = 0;
  BOOL success = ReadFile(h, buffer, 1, &read, NULL);
  if (!success && (GetLastError() != ERROR_BROKEN_PIPE)) {
    return false;
  }
  *byte = (read == 1) ? buffer[0] : -1;
  return true;
}

bool Stdin::GetEchoMode(intptr_t fd, bool* enabled) {
  HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
  DWORD mode;
  if (!GetConsoleMode(h, &mode)) {
    return false;
  }
  *enabled = ((mode & ENABLE_ECHO_INPUT) != 0);
  return true;
}

bool Stdin::SetEchoMode(intptr_t fd, bool enabled) {
  HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
  DWORD mode;
  if (!GetConsoleMode(h, &mode)) {
    return false;
  }
  if (enabled) {
    mode |= ENABLE_ECHO_INPUT;
  } else {
    mode &= ~ENABLE_ECHO_INPUT;
  }
  return SetConsoleMode(h, mode);
}

bool Stdin::GetEchoNewlineMode(intptr_t fd, bool* enabled) {
  *enabled = false;
  return true;
}

bool Stdin::SetEchoNewlineMode(intptr_t fd, bool enabled) {
  if (enabled) {
    SetLastError(ERROR_NOT_CAPABLE);
    return false;
  }
  return true;
}

bool Stdin::GetLineMode(intptr_t fd, bool* enabled) {
  HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
  DWORD mode;
  if (!GetConsoleMode(h, &mode)) {
    return false;
  }
  *enabled = (mode & ENABLE_LINE_INPUT) != 0;
  return true;
}

bool Stdin::SetLineMode(intptr_t fd, bool enabled) {
  HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
  DWORD mode;
  if (!GetConsoleMode(h, &mode)) {
    return false;
  }
  if (enabled) {
    mode |= ENABLE_LINE_INPUT;
  } else {
    mode &= ~ENABLE_LINE_INPUT;
  }
  return SetConsoleMode(h, mode);
}

bool Stdin::AnsiSupported(intptr_t fd, bool* supported) {
  ASSERT(supported != NULL);
  HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
  if (h == INVALID_HANDLE_VALUE) {
    *supported = false;
    return true;
  }
  DWORD mode;
  if (!GetConsoleMode(h, &mode)) {
    *supported = false;
    return true;
  }
  *supported = (mode & ENABLE_VIRTUAL_TERMINAL_INPUT) != 0;
  return true;
}

bool Stdout::GetTerminalSize(intptr_t fd, int size[2]) {
  HANDLE h;
  if (fd == 1) {
    h = GetStdHandle(STD_OUTPUT_HANDLE);
  } else {
    h = GetStdHandle(STD_ERROR_HANDLE);
  }
  CONSOLE_SCREEN_BUFFER_INFO info;
  if (!GetConsoleScreenBufferInfo(h, &info)) {
    return false;
  }
  size[0] = info.srWindow.Right - info.srWindow.Left + 1;
  size[1] = info.srWindow.Bottom - info.srWindow.Top + 1;
  return true;
}

bool Stdout::AnsiSupported(intptr_t fd, bool* supported) {
  ASSERT(supported != NULL);
  HANDLE h;
  if (fd == 1) {
    h = GetStdHandle(STD_OUTPUT_HANDLE);
  } else {
    h = GetStdHandle(STD_ERROR_HANDLE);
  }
  if (h == INVALID_HANDLE_VALUE) {
    *supported = false;
    return true;
  }
  DWORD mode;
  if (!GetConsoleMode(h, &mode)) {
    *supported = false;
    return true;
  }
  *supported = (mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0;
  return true;
}

}  // namespace bin
}  // namespace dart

#endif  // defined(DART_HOST_OS_WINDOWS)
