// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <assert.h>
#include <iostream>
#include <memory>
#include <string>

#include "keyboard_manager_win32.h"

#include "keyboard_win32_common.h"

namespace flutter {

namespace {

// The maximum number of pending events to keep before
// emitting a warning on the console about unhandled events.
static constexpr int kMaxPendingEvents = 1000;

// Returns true if this key is an AltRight key down event.
//
// This is used to resolve an issue where an AltGr press causes CtrlLeft to hang
// when pressed, as reported in https://github.com/flutter/flutter/issues/78005.
//
// When AltGr is pressed (in a supporting layout such as Spanish), Win32 first
// fires a fake CtrlLeft down event, then an AltRight down event.
// This is significant because this fake CtrlLeft down event will not be paired
// with a up event, which is fine until Flutter redispatches the CtrlDown
// event, which Win32 then interprets as a real event, leaving both Win32 and
// the Flutter framework thinking that CtrlLeft is still pressed.
//
// To resolve this, Flutter recognizes this fake CtrlLeft down event using the
// following AltRight down event. Flutter then synthesizes a CtrlLeft key up
// event immediately after the corresponding AltRight key up event.
//
// One catch is that it is impossible to distinguish the fake CtrlLeft down
// from a normal CtrlLeft down (followed by a AltRight down), since they
// contain the exactly same information, including the GetKeyState result.
// Fortunately, this will require the two events to occur *really* close, which
// would be rare, and a misrecognition would only cause a minor consequence
// where the CtrlLeft is released early; the later, real, CtrlLeft up event will
// be ignored.
static bool IsKeyDownAltRight(int action, int virtual_key, bool extended) {
#ifdef WINUWP
  return false;
#else
  return virtual_key == VK_RMENU && extended &&
         (action == WM_KEYDOWN || action == WM_SYSKEYDOWN);
#endif
}

// Returns true if this key is a key up event of AltRight.
//
// This is used to assist a corner case described in |IsKeyDownAltRight|.
static bool IsKeyUpAltRight(int action, int virtual_key, bool extended) {
#ifdef WINUWP
  return false;
#else
  return virtual_key == VK_RMENU && extended &&
         (action == WM_KEYUP || action == WM_SYSKEYUP);
#endif
}

// Returns true if this key is a key down event of CtrlLeft.
//
// This is used to assist a corner case described in |IsKeyDownAltRight|.
static bool IsKeyDownCtrlLeft(int action, int virtual_key) {
#ifdef WINUWP
  return false;
#else
  return virtual_key == VK_LCONTROL &&
         (action == WM_KEYDOWN || action == WM_SYSKEYDOWN);
#endif
}

// Returns true if this key is a key down event of ShiftRight.
//
// This is a temporary solution to
// https://github.com/flutter/flutter/issues/81674, and forces ShiftRight
// KeyDown events to not be redispatched regardless of the framework's response.
//
// If a ShiftRight KeyDown event is not handled by the framework and is
// redispatched, Win32 will not send its following KeyUp event and keeps
// recording ShiftRight as being pressed.
static bool IsKeyDownShiftRight(int virtual_key, bool was_down) {
#ifdef WINUWP
  return false;
#else
  return virtual_key == VK_RSHIFT && !was_down;
#endif
}

// Returns if a character sent by Win32 is a dead key.
static bool IsDeadKey(uint32_t ch) {
  return (ch & kDeadKeyCharMask) != 0;
}

static char32_t CodePointFromSurrogatePair(wchar_t high, wchar_t low) {
  return 0x10000 + ((static_cast<char32_t>(high) & 0x000003FF) << 10) +
         (low & 0x3FF);
}

static uint16_t ResolveKeyCode(uint16_t original,
                               bool extended,
                               uint8_t scancode) {
  switch (original) {
    case VK_SHIFT:
    case VK_LSHIFT:
      return MapVirtualKey(scancode, MAPVK_VSC_TO_VK_EX);
    case VK_MENU:
    case VK_LMENU:
      return extended ? VK_RMENU : VK_LMENU;
    case VK_CONTROL:
    case VK_LCONTROL:
      return extended ? VK_RCONTROL : VK_LCONTROL;
    default:
      return original;
  }
}

static bool IsPrintable(uint32_t c) {
  constexpr char32_t kMinPrintable = ' ';
  constexpr char32_t kDelete = 0x7F;
  return c >= kMinPrintable && c != kDelete;
}

}  // namespace

KeyboardManagerWin32::KeyboardManagerWin32(WindowDelegate* delegate)
    : window_delegate_(delegate),
      last_key_is_ctrl_left_down(false),
      should_synthesize_ctrl_left_up(false) {}

void KeyboardManagerWin32::RedispatchEvent(
    std::unique_ptr<PendingEvent> event) {
  for (const Win32Message& message : event->session) {
    pending_redispatches_.push_back(message);
    UINT result = window_delegate_->Win32DispatchMessage(
        message.action, message.wparam, message.lparam);
    if (result != 0) {
      std::cerr << "Unable to synthesize event for keyboard event."
                << std::endl;
    }
  }
  if (pending_redispatches_.size() > kMaxPendingEvents) {
    std::cerr
        << "There are " << pending_redispatches_.size()
        << " keyboard events that have not yet received a response from the "
        << "framework. Are responses being sent?" << std::endl;
  }
}

bool KeyboardManagerWin32::RemoveRedispatchedMessage(UINT const action,
                                                     WPARAM const wparam,
                                                     LPARAM const lparam) {
  for (auto iter = pending_redispatches_.begin();
       iter != pending_redispatches_.end(); ++iter) {
    if (action == iter->action && wparam == iter->wparam) {
      pending_redispatches_.erase(iter);
      return true;
    }
  }
  return false;
}

void KeyboardManagerWin32::OnKey(std::unique_ptr<PendingEvent> event,
                                 OnKeyCallback callback) {
  if (IsKeyDownAltRight(event->action, event->key, event->extended)) {
    if (last_key_is_ctrl_left_down) {
      should_synthesize_ctrl_left_up = true;
    }
  }
  if (IsKeyDownCtrlLeft(event->action, event->key)) {
    last_key_is_ctrl_left_down = true;
    ctrl_left_scancode = event->scancode;
    should_synthesize_ctrl_left_up = false;
  } else {
    last_key_is_ctrl_left_down = false;
  }
  if (IsKeyUpAltRight(event->action, event->key, event->extended)) {
    if (should_synthesize_ctrl_left_up) {
      should_synthesize_ctrl_left_up = false;
      const LPARAM lParam =
          (1 /* repeat_count */ << 0) | (ctrl_left_scancode << 16) |
          (0 /* extended */ << 24) | (1 /* prev_state */ << 30) |
          (1 /* transition */ << 31);
      window_delegate_->Win32DispatchMessage(WM_KEYUP, VK_LCONTROL, lParam);
    }
  }

  const PendingEvent clone = *event;
  window_delegate_->OnKey(clone.key, clone.scancode, clone.action,
                          clone.character, clone.extended, clone.was_down,
                          [this, event = event.release(),
                           callback = std::move(callback)](bool handled) {
                            callback(std::unique_ptr<PendingEvent>(event),
                                     handled);
                          });
}

void KeyboardManagerWin32::DispatchReadyTexts() {
  auto front = pending_texts_.begin();
  for (; front != pending_texts_.end() && front->ready; ++front) {
    window_delegate_->OnText(front->content);
  }
  pending_texts_.erase(pending_texts_.begin(), front);
}

void KeyboardManagerWin32::HandleOnKeyResult(
    std::unique_ptr<PendingEvent> event,
    bool handled,
    std::list<PendingText>::iterator pending_text) {
  // First, patch |handled|, because some key events must always be treated as
  // handled.
  //
  // Redispatching dead keys events makes Win32 ignore the dead key state
  // and redispatches a normal character without combining it with the
  // next letter key.
  //
  // Redispatching sys events is impossible due to the limitation of
  // |SendInput|.
  const bool is_syskey =
      event->action == WM_SYSKEYDOWN || event->action == WM_SYSKEYUP;
  const bool real_handled = handled || IsDeadKey(event->character) ||
                            is_syskey ||
                            IsKeyDownShiftRight(event->key, event->was_down);

  // For handled events, that's all.
  if (real_handled) {
    if (pending_text != pending_texts_.end()) {
      pending_texts_.erase(pending_text);
    }
    return;
  }

  // For unhandled events, dispatch them to OnText.

  if (pending_text != pending_texts_.end()) {
    pending_text->ready = true;
    DispatchReadyTexts();
  }

  RedispatchEvent(std::move(event));
}

bool KeyboardManagerWin32::HandleMessage(UINT const action,
                                         WPARAM const wparam,
                                         LPARAM const lparam) {
  if (RemoveRedispatchedMessage(action, wparam, lparam)) {
    return false;
  }
  switch (action) {
    case WM_DEADCHAR:
    case WM_SYSDEADCHAR:
    case WM_CHAR:
    case WM_SYSCHAR: {
      const Win32Message message =
          Win32Message{.action = action, .wparam = wparam, .lparam = lparam};
      current_session_.push_back(message);

      std::u16string text;
      char32_t code_point;
      if (message.IsHighSurrogate()) {
        // A high surrogate is always followed by a low surrogate.  Process the
        // session later and consider this message as handled.
        return true;
      } else if (message.IsLowSurrogate()) {
        const Win32Message* last_message =
            current_session_.size() <= 1
                ? nullptr
                : &current_session_[current_session_.size() - 2];
        if (last_message == nullptr || !last_message->IsHighSurrogate()) {
          return false;
        }
        // A low surrogate always follows a high surrogate, marking the end of
        // a char session. Process the session after the if clause.
        text.push_back(static_cast<wchar_t>(last_message->wparam));
        text.push_back(static_cast<wchar_t>(message.wparam));
        code_point =
            CodePointFromSurrogatePair(last_message->wparam, message.wparam);
      } else {
        // A non-surrogate character always appears alone. Process the session
        // after the if clause.
        text.push_back(static_cast<wchar_t>(message.wparam));
        code_point = static_cast<wchar_t>(message.wparam);
      }

      // If this char message is preceded by a key down message, then dispatch
      // the key down message as a key down event first, and only dispatch the
      // OnText if the key down event is not handled.
      if (current_session_.front().IsGeneralKeyDown()) {
        const Win32Message first_message = current_session_.front();
        const uint8_t scancode = (lparam >> 16) & 0xff;
        const uint16_t key_code = first_message.wparam;
        const bool extended = ((lparam >> 24) & 0x01) == 0x01;
        const bool was_down = lparam & 0x40000000;
        // Certain key combinations yield control characters as WM_CHAR's
        // lParam. For example, 0x01 for Ctrl-A. Filter these characters. See
        // https://docs.microsoft.com/en-us/windows/win32/learnwin32/accelerator-tables
        char32_t character;
        if (action == WM_DEADCHAR || action == WM_SYSDEADCHAR) {
          // Mask the resulting char with kDeadKeyCharMask anyway, because in
          // rare cases the bit is *not* set (US INTL Shift-6 circumflex, see
          // https://github.com/flutter/flutter/issues/92654 .)
          character =
              window_delegate_->Win32MapVkToChar(key_code) | kDeadKeyCharMask;
        } else {
          character = IsPrintable(code_point) ? code_point : 0;
        }
        auto event = std::make_unique<PendingEvent>(PendingEvent{
            .key = key_code,
            .scancode = scancode,
            .action = static_cast<UINT>(action == WM_SYSCHAR ? WM_SYSKEYDOWN
                                                             : WM_KEYDOWN),
            .character = character,
            .extended = extended,
            .was_down = was_down,
            .session = std::move(current_session_),
        });
        // Compute the text that might be dispatched later.
        //
        // Of the messages handled here, only WM_CHAR should be treated as
        // characters. WM_SYS*CHAR are not part of text input, and WM_DEADCHAR
        // will be incorporated into a later WM_CHAR with the full character.
        //
        // Checking `character` filters out non-printable event characters.
        std::list<PendingText>::iterator pending_text;
        if (action == WM_CHAR && character != 0) {
          pending_texts_.push_back(PendingText{
              .ready = false,
              .content = text,
          });
          pending_text = std::prev(pending_texts_.end());
        } else {
          pending_text = pending_texts_.end();
        }
        // SYS messages must not be handled by `HandleMessage` or be
        // redispatched.
        const bool is_syskey = action == WM_SYSCHAR || action == WM_SYSDEADCHAR;
        OnKey(std::move(event),
              [this, pending_text, is_syskey](
                  std::unique_ptr<PendingEvent> event, bool handled) {
                bool real_handled = handled || is_syskey;
                HandleOnKeyResult(std::move(event), handled, pending_text);
              });
        return !is_syskey;
      }

      // If the charcter session is not preceded by a key down message, dispatch
      // the OnText immediately.

      // Only WM_CHAR should be treated as characters. WM_SYS*CHAR are not part
      // of text input, and WM_DEADCHAR will be incorporated into a later
      // WM_CHAR with the full character.
      //
      // Also filter out ASCII control characters, which are sent as WM_CHAR
      // events for all control key shortcuts.
      current_session_.clear();
      if (action == WM_CHAR && IsPrintable(wparam)) {
        pending_texts_.push_back(PendingText{
            .ready = true,
            .content = text,
        });
        DispatchReadyTexts();
      }
      return true;
    }

    case WM_KEYDOWN:
    case WM_SYSKEYDOWN:
    case WM_KEYUP:
    case WM_SYSKEYUP: {
      current_session_.clear();
      current_session_.push_back(
          Win32Message{.action = action, .wparam = wparam, .lparam = lparam});
      const bool is_keydown_message =
          (action == WM_KEYDOWN || action == WM_SYSKEYDOWN);
      // Check if this key produces a character. If so, the key press should
      // be sent with the character produced at WM_CHAR. Store the produced
      // keycode (it's not accessible from WM_CHAR) to be used in WM_CHAR.
      //
      // Messages with Control or Win modifiers down are never considered as
      // character messages. This allows key combinations such as "CTRL + Digit"
      // to properly produce key down events even though `MapVirtualKey` returns
      // a valid character. See https://github.com/flutter/flutter/issues/85587.
      unsigned int character = window_delegate_->Win32MapVkToChar(wparam);
      UINT next_key_message = PeekNextMessageType(WM_KEYFIRST, WM_KEYLAST);
      bool has_wm_char =
          (next_key_message == WM_DEADCHAR ||
           next_key_message == WM_SYSDEADCHAR || next_key_message == WM_CHAR ||
           next_key_message == WM_SYSCHAR);
      if (character > 0 && is_keydown_message && has_wm_char) {
        // This key down message has following char events. Process later,
        // because the character for the OnKey should be decided by the char
        // events. Consider this event as handled.
        return true;
      }

      // Resolve session: A non-char key event.
      const uint8_t scancode = (lparam >> 16) & 0xff;
      const bool extended = ((lparam >> 24) & 0x01) == 0x01;
      // If the key is a modifier, get its side.
      const uint16_t key_code = ResolveKeyCode(wparam, extended, scancode);
      const bool was_down = lparam & 0x40000000;
      auto event = std::make_unique<PendingEvent>(PendingEvent{
          .key = key_code,
          .scancode = scancode,
          .action = action,
          .character = 0,
          .extended = extended,
          .was_down = was_down,
          .session = std::move(current_session_),
      });
      // SYS messages must not be handled by `HandleMessage` or be
      // redispatched.
      const bool is_syskey = action == WM_SYSKEYDOWN || action == WM_SYSKEYUP;
      OnKey(
          std::move(event),
          [this, is_syskey](std::unique_ptr<PendingEvent> event, bool handled) {
            bool real_handled = handled || is_syskey;
            HandleOnKeyResult(std::move(event), handled, pending_texts_.end());
          });
      return !is_syskey;
    }
    default:
      assert(false);
  }
  return false;
}

UINT KeyboardManagerWin32::PeekNextMessageType(UINT wMsgFilterMin,
                                               UINT wMsgFilterMax) {
  MSG next_message;
  BOOL has_msg = window_delegate_->Win32PeekMessage(
      &next_message, wMsgFilterMin, wMsgFilterMax, PM_NOREMOVE);
  if (!has_msg) {
    return 0;
  }
  return next_message.message;
}

uint64_t KeyboardManagerWin32::ComputeEventHash(const PendingEvent& event) {
  // Calculate a key event ID based on the scan code of the key pressed,
  // and the flags we care about.
  return event.scancode | (((event.action == WM_KEYUP ? KEYEVENTF_KEYUP : 0x0) |
                            (event.extended ? KEYEVENTF_EXTENDEDKEY : 0x0))
                           << 16);
}

}  // namespace flutter
