// Copyright (c) 2016 The Chromium Embedded Framework 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 "tests/shared/browser/main_message_loop_external_pump.h"

#include <CommCtrl.h>

#include "include/cef_app.h"
#include "tests/shared/browser/util_win.h"

namespace client {

namespace {

// Message sent to get an additional time slice for pumping (processing) another
// task (a series of such messages creates a continuous task pump).
static const int kMsgHaveWork = WM_USER + 1;

class MainMessageLoopExternalPumpWin : public MainMessageLoopExternalPump {
 public:
  MainMessageLoopExternalPumpWin();
  ~MainMessageLoopExternalPumpWin();

  // MainMessageLoopStd methods:
  void Quit() OVERRIDE;
  int Run() OVERRIDE;

  // MainMessageLoopExternalPump methods:
  void OnScheduleMessagePumpWork(int64 delay_ms) OVERRIDE;

 protected:
  // MainMessageLoopExternalPump methods:
  void SetTimer(int64 delay_ms) OVERRIDE;
  void KillTimer() OVERRIDE;
  bool IsTimerPending() OVERRIDE { return timer_pending_; }

 private:
  static LRESULT CALLBACK WndProc(HWND hwnd,
                                  UINT msg,
                                  WPARAM wparam,
                                  LPARAM lparam);

  // True if a timer event is currently pending.
  bool timer_pending_;

  // HWND owned by the thread that CefDoMessageLoopWork should be invoked on.
  HWND main_thread_target_;
};

MainMessageLoopExternalPumpWin::MainMessageLoopExternalPumpWin()
    : timer_pending_(false), main_thread_target_(NULL) {
  HINSTANCE hInstance = GetModuleHandle(NULL);
  const wchar_t* const kClassName = L"CEFMainTargetHWND";

  WNDCLASSEX wcex = {};
  wcex.cbSize = sizeof(WNDCLASSEX);
  wcex.lpfnWndProc = WndProc;
  wcex.hInstance = hInstance;
  wcex.lpszClassName = kClassName;
  RegisterClassEx(&wcex);

  // Create the message handling window.
  main_thread_target_ =
      CreateWindowW(kClassName, NULL, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0,
                    HWND_MESSAGE, NULL, hInstance, NULL);
  DCHECK(main_thread_target_);
  SetUserDataPtr(main_thread_target_, this);
}

MainMessageLoopExternalPumpWin::~MainMessageLoopExternalPumpWin() {
  KillTimer();
  if (main_thread_target_)
    DestroyWindow(main_thread_target_);
}

void MainMessageLoopExternalPumpWin::Quit() {
  PostMessage(NULL, WM_QUIT, 0, 0);
}

int MainMessageLoopExternalPumpWin::Run() {
  // Run the message loop.
  MSG msg;
  while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  KillTimer();

  // We need to run the message pump until it is idle. However we don't have
  // that information here so we run the message loop "for a while".
  for (int i = 0; i < 10; ++i) {
    // Do some work.
    CefDoMessageLoopWork();

    // Sleep to allow the CEF proc to do work.
    Sleep(50);
  }

  return 0;
}

void MainMessageLoopExternalPumpWin::OnScheduleMessagePumpWork(int64 delay_ms) {
  // This method may be called on any thread.
  PostMessage(main_thread_target_, kMsgHaveWork, 0,
              static_cast<LPARAM>(delay_ms));
}

void MainMessageLoopExternalPumpWin::SetTimer(int64 delay_ms) {
  DCHECK(!timer_pending_);
  DCHECK_GT(delay_ms, 0);
  timer_pending_ = true;
  ::SetTimer(main_thread_target_, 1, static_cast<UINT>(delay_ms), NULL);
}

void MainMessageLoopExternalPumpWin::KillTimer() {
  if (timer_pending_) {
    ::KillTimer(main_thread_target_, 1);
    timer_pending_ = false;
  }
}

// static
LRESULT CALLBACK MainMessageLoopExternalPumpWin::WndProc(HWND hwnd,
                                                         UINT msg,
                                                         WPARAM wparam,
                                                         LPARAM lparam) {
  if (msg == WM_TIMER || msg == kMsgHaveWork) {
    MainMessageLoopExternalPumpWin* message_loop =
        GetUserDataPtr<MainMessageLoopExternalPumpWin*>(hwnd);
    if (msg == kMsgHaveWork) {
      // OnScheduleMessagePumpWork() request.
      const int64 delay_ms = static_cast<int64>(lparam);
      message_loop->OnScheduleWork(delay_ms);
    } else {
      // Timer timed out.
      message_loop->OnTimerTimeout();
    }
  }
  return DefWindowProc(hwnd, msg, wparam, lparam);
}

}  // namespace

// static
scoped_ptr<MainMessageLoopExternalPump> MainMessageLoopExternalPump::Create() {
  return scoped_ptr<MainMessageLoopExternalPump>(
      new MainMessageLoopExternalPumpWin());
}

}  // namespace client
