// Copyright 2019 The Chromium 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 "ui/gfx/win/singleton_hwnd_hot_key_observer.h"

#include "base/bind.h"
#include "base/containers/flat_set.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/win/singleton_hwnd.h"

namespace gfx {

namespace {

base::flat_set<int>& GetUsedHotKeyIDs() {
  static base::NoDestructor<base::flat_set<int>> used_hot_key_ids;
  return *used_hot_key_ids;
}

absl::optional<int> GetAvailableHotKeyID() {
  // Valid hot key IDs are in the range 0x0000 to 0xBFFF. See
  // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registerhotkey
  for (int i = 0x0000; i < 0xBFFF; i++) {
    if (!GetUsedHotKeyIDs().contains(i))
      return i;
  }
  return absl::nullopt;
}

void SetHotKeyIDUsed(int id) {
  DCHECK(!GetUsedHotKeyIDs().contains(id));
  GetUsedHotKeyIDs().insert(id);
}

void SetHotKeyIDAvailable(int id) {
  DCHECK(GetUsedHotKeyIDs().contains(id));
  GetUsedHotKeyIDs().erase(id);
}

}  // anonymous namespace

std::unique_ptr<SingletonHwndHotKeyObserver>
SingletonHwndHotKeyObserver::Create(
    const SingletonHwndObserver::WndProc& wnd_proc,
    UINT key_code,
    int modifiers) {
  absl::optional<int> hot_key_id = GetAvailableHotKeyID();

  // If there are no available hot key IDs, return null.
  if (!hot_key_id.has_value())
    return nullptr;

  // If we fail to register the hot key, return null. Most likely reason for
  // failure is that another application has already registered the hot key.
  if (!RegisterHotKey(gfx::SingletonHwnd::GetInstance()->hwnd(), *hot_key_id,
                      modifiers, key_code)) {
    return nullptr;
  }

  return base::WrapUnique(
      new SingletonHwndHotKeyObserver(wnd_proc, *hot_key_id));
}

SingletonHwndHotKeyObserver::SingletonHwndHotKeyObserver(
    const SingletonHwndObserver::WndProc& wnd_proc,
    int hot_key_id)
    : observer_(base::BindRepeating(&SingletonHwndHotKeyObserver::OnWndProc,
                                    base::Unretained(this))),
      wnd_proc_(wnd_proc),
      hot_key_id_(hot_key_id) {
  SetHotKeyIDUsed(hot_key_id);
}

SingletonHwndHotKeyObserver::~SingletonHwndHotKeyObserver() {
  bool success = !!UnregisterHotKey(gfx::SingletonHwnd::GetInstance()->hwnd(),
                                    hot_key_id_);
  // This call should always succeed, as long as we pass in the right HWND and
  // an id we've used to register before.
  DCHECK(success);
  SetHotKeyIDAvailable(hot_key_id_);
}

void SingletonHwndHotKeyObserver::OnWndProc(HWND hwnd,
                                            UINT message,
                                            WPARAM wparam,
                                            LPARAM lparam) {
  // Only propagate WM_HOTKEY messages for this particular hot key to the owner
  // of this observer.
  if (message == WM_HOTKEY && static_cast<int>(wparam) == hot_key_id_)
    wnd_proc_.Run(hwnd, message, wparam, lparam);
}

}  // namespace gfx
