/*
 *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/desktop_capture/win/window_capture_utils.h"

#include <winuser.h>
#include <algorithm>
#include <memory>
#include <mutex>

#include "modules/desktop_capture/desktop_capturer.h"
#include "modules/desktop_capture/win/test_support/test_window.h"
#include "rtc_base/thread.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

const char kWindowThreadName[] = "window_capture_utils_test_thread";
const WCHAR kWindowTitle[] = L"Window Capture Utils Test";

std::unique_ptr<rtc::Thread> SetUpUnresponsiveWindow(std::mutex& mtx,
                                                     WindowInfo& info) {
  std::unique_ptr<rtc::Thread> window_thread;
  window_thread = rtc::Thread::Create();
  window_thread->SetName(kWindowThreadName, nullptr);
  window_thread->Start();

  window_thread->Invoke<void>(
      RTC_FROM_HERE, [&info]() { info = CreateTestWindow(kWindowTitle); });

  // Intentionally create a deadlock to cause the window to become unresponsive.
  mtx.lock();
  window_thread->PostTask(RTC_FROM_HERE, [&mtx]() {
    mtx.lock();
    mtx.unlock();
  });

  return window_thread;
}

}  // namespace

TEST(WindowCaptureUtilsTest, GetWindowList) {
  WindowInfo info = CreateTestWindow(kWindowTitle);
  DesktopCapturer::SourceList window_list;
  ASSERT_TRUE(GetWindowList(GetWindowListFlags::kNone, &window_list));
  EXPECT_GT(window_list.size(), 0ULL);
  EXPECT_NE(std::find_if(window_list.begin(), window_list.end(),
                         [&info](DesktopCapturer::Source window) {
                           return reinterpret_cast<HWND>(window.id) ==
                                  info.hwnd;
                         }),
            window_list.end());
  DestroyTestWindow(info);
}

TEST(WindowCaptureUtilsTest, IncludeUnresponsiveWindows) {
  std::mutex mtx;
  WindowInfo info;
  std::unique_ptr<rtc::Thread> window_thread =
      SetUpUnresponsiveWindow(mtx, info);

  EXPECT_FALSE(IsWindowResponding(info.hwnd));

  DesktopCapturer::SourceList window_list;
  ASSERT_TRUE(GetWindowList(GetWindowListFlags::kNone, &window_list));
  EXPECT_GT(window_list.size(), 0ULL);
  EXPECT_NE(std::find_if(window_list.begin(), window_list.end(),
                         [&info](DesktopCapturer::Source window) {
                           return reinterpret_cast<HWND>(window.id) ==
                                  info.hwnd;
                         }),
            window_list.end());

  mtx.unlock();
  window_thread->Invoke<void>(RTC_FROM_HERE,
                              [&info]() { DestroyTestWindow(info); });
  window_thread->Stop();
}

TEST(WindowCaptureUtilsTest, IgnoreUnresponsiveWindows) {
  std::mutex mtx;
  WindowInfo info;
  std::unique_ptr<rtc::Thread> window_thread =
      SetUpUnresponsiveWindow(mtx, info);

  EXPECT_FALSE(IsWindowResponding(info.hwnd));

  DesktopCapturer::SourceList window_list;
  ASSERT_TRUE(
      GetWindowList(GetWindowListFlags::kIgnoreUnresponsive, &window_list));
  EXPECT_EQ(std::find_if(window_list.begin(), window_list.end(),
                         [&info](DesktopCapturer::Source window) {
                           return reinterpret_cast<HWND>(window.id) ==
                                  info.hwnd;
                         }),
            window_list.end());

  mtx.unlock();
  window_thread->Invoke<void>(RTC_FROM_HERE,
                              [&info]() { DestroyTestWindow(info); });
  window_thread->Stop();
}

TEST(WindowCaptureUtilsTest, IncludeUntitledWindows) {
  WindowInfo info = CreateTestWindow(L"");
  DesktopCapturer::SourceList window_list;
  ASSERT_TRUE(GetWindowList(GetWindowListFlags::kNone, &window_list));
  EXPECT_GT(window_list.size(), 0ULL);
  EXPECT_NE(std::find_if(window_list.begin(), window_list.end(),
                         [&info](DesktopCapturer::Source window) {
                           return reinterpret_cast<HWND>(window.id) ==
                                  info.hwnd;
                         }),
            window_list.end());
  DestroyTestWindow(info);
}

TEST(WindowCaptureUtilsTest, IgnoreUntitledWindows) {
  WindowInfo info = CreateTestWindow(L"");
  DesktopCapturer::SourceList window_list;
  ASSERT_TRUE(GetWindowList(GetWindowListFlags::kIgnoreUntitled, &window_list));
  EXPECT_EQ(std::find_if(window_list.begin(), window_list.end(),
                         [&info](DesktopCapturer::Source window) {
                           return reinterpret_cast<HWND>(window.id) ==
                                  info.hwnd;
                         }),
            window_list.end());
  DestroyTestWindow(info);
}

TEST(WindowCaptureUtilsTest, IgnoreCurrentProcessWindows) {
  WindowInfo info = CreateTestWindow(kWindowTitle);
  DesktopCapturer::SourceList window_list;
  ASSERT_TRUE(GetWindowList(GetWindowListFlags::kIgnoreCurrentProcessWindows,
                            &window_list));
  EXPECT_EQ(std::find_if(window_list.begin(), window_list.end(),
                         [&info](DesktopCapturer::Source window) {
                           return reinterpret_cast<HWND>(window.id) ==
                                  info.hwnd;
                         }),
            window_list.end());
  DestroyTestWindow(info);
}

}  // namespace webrtc
