/*
 *  Copyright (c) 2016 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 <string.h>

#include <algorithm>
#include <initializer_list>
#include <iostream>  // TODO(zijiehe): Remove once flaky has been resolved.
#include <memory>
#include <utility>

// TODO(zijiehe): Remove once flaky has been resolved.
#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "webrtc/modules/desktop_capture/desktop_capturer.h"
#include "webrtc/modules/desktop_capture/desktop_frame.h"
#include "webrtc/modules/desktop_capture/desktop_region.h"
#include "webrtc/modules/desktop_capture/mock_desktop_capturer_callback.h"
#include "webrtc/modules/desktop_capture/rgba_color.h"
#include "webrtc/modules/desktop_capture/screen_drawer.h"
#include "webrtc/rtc_base/base64.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/constructormagic.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"

#if defined(WEBRTC_WIN)
#include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
#include "webrtc/rtc_base/win32.h"
#endif  // defined(WEBRTC_WIN)

using ::testing::_;

namespace webrtc {

namespace {

ACTION_P2(SaveCaptureResult, result, dest) {
  *result = arg0;
  *dest = std::move(*arg1);
}

// Returns true if color in |rect| of |frame| is |color|.
bool ArePixelsColoredBy(const DesktopFrame& frame,
                        DesktopRect rect,
                        RgbaColor color,
                        bool may_partially_draw) {
  if (!may_partially_draw) {
    // updated_region() should cover the painted area.
    DesktopRegion updated_region(frame.updated_region());
    updated_region.IntersectWith(rect);
    if (!updated_region.Equals(DesktopRegion(rect))) {
      return false;
    }
  }

  // Color in the |rect| should be |color|.
  uint8_t* row = frame.GetFrameDataAtPos(rect.top_left());
  for (int i = 0; i < rect.height(); i++) {
    uint8_t* column = row;
    for (int j = 0; j < rect.width(); j++) {
      if (color != RgbaColor(column)) {
        return false;
      }
      column += DesktopFrame::kBytesPerPixel;
    }
    row += frame.stride();
  }
  return true;
}

}  // namespace

class ScreenCapturerIntegrationTest : public testing::Test {
 public:
  void SetUp() override {
    capturer_ = DesktopCapturer::CreateScreenCapturer(
        DesktopCaptureOptions::CreateDefault());
  }

 protected:
  void TestCaptureUpdatedRegion(
      std::initializer_list<DesktopCapturer*> capturers) {
    RTC_DCHECK(capturers.size() > 0);
    // A large enough area for the tests, which should be able to be fulfilled
    // by most systems.
#if defined(WEBRTC_WIN)
    // On Windows, an interesting warning window may pop up randomly. The root
    // cause is still under investigation, so reduce the test area to work
    // around. Bug https://bugs.chromium.org/p/webrtc/issues/detail?id=6666.
    const int kTestArea = 416;
#else
    const int kTestArea = 512;
#endif
    const int kRectSize = 32;
    std::unique_ptr<ScreenDrawer> drawer = ScreenDrawer::Create();
    if (!drawer || drawer->DrawableRegion().is_empty()) {
      LOG(LS_WARNING) << "No ScreenDrawer implementation for current platform.";
      return;
    }
    if (drawer->DrawableRegion().width() < kTestArea ||
        drawer->DrawableRegion().height() < kTestArea) {
      LOG(LS_WARNING) << "ScreenDrawer::DrawableRegion() is too small for the "
                         "CaptureUpdatedRegion tests.";
      return;
    }

    for (DesktopCapturer* capturer : capturers) {
      capturer->Start(&callback_);
    }

    // Draw a set of |kRectSize| by |kRectSize| rectangles at (|i|, |i|), or
    // |i| by |i| rectangles at (|kRectSize|, |kRectSize|). One of (controlled
    // by |c|) its primary colors is |i|, and the other two are 0x7f. So we
    // won't draw a black or white rectangle.
    for (int c = 0; c < 3; c++) {
      // A fixed size rectangle.
      for (int i = 0; i < kTestArea - kRectSize; i += 16) {
        DesktopRect rect = DesktopRect::MakeXYWH(i, i, kRectSize, kRectSize);
        rect.Translate(drawer->DrawableRegion().top_left());
        RgbaColor color((c == 0 ? (i & 0xff) : 0x7f),
                        (c == 1 ? (i & 0xff) : 0x7f),
                        (c == 2 ? (i & 0xff) : 0x7f));
        // Fail fast.
        ASSERT_NO_FATAL_FAILURE(
            TestCaptureOneFrame(capturers, drawer.get(), rect, color));
      }

      // A variable-size rectangle.
      for (int i = 0; i < kTestArea - kRectSize; i += 16) {
        DesktopRect rect = DesktopRect::MakeXYWH(kRectSize, kRectSize, i, i);
        rect.Translate(drawer->DrawableRegion().top_left());
        RgbaColor color((c == 0 ? (i & 0xff) : 0x7f),
                        (c == 1 ? (i & 0xff) : 0x7f),
                        (c == 2 ? (i & 0xff) : 0x7f));
        // Fail fast.
        ASSERT_NO_FATAL_FAILURE(
            TestCaptureOneFrame(capturers, drawer.get(), rect, color));
      }
    }
  }

  void TestCaptureUpdatedRegion() {
    TestCaptureUpdatedRegion({capturer_.get()});
  }

#if defined(WEBRTC_WIN)
  // Enable allow_directx_capturer in DesktopCaptureOptions, but let
  // DesktopCapturer::CreateScreenCapturer() to decide whether a DirectX
  // capturer should be used.
  void MaybeCreateDirectxCapturer() {
    DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
    options.set_allow_directx_capturer(true);
    capturer_ = DesktopCapturer::CreateScreenCapturer(options);
  }

  bool CreateDirectxCapturer() {
    if (!ScreenCapturerWinDirectx::IsSupported()) {
      LOG(LS_WARNING) << "Directx capturer is not supported";
      return false;
    }

    MaybeCreateDirectxCapturer();
    return true;
  }

  void CreateMagnifierCapturer() {
    DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
    options.set_allow_use_magnification_api(true);
    capturer_ = DesktopCapturer::CreateScreenCapturer(options);
  }
#endif  // defined(WEBRTC_WIN)

  std::unique_ptr<DesktopCapturer> capturer_;
  MockDesktopCapturerCallback callback_;

 private:
  // Repeats capturing the frame by using |capturers| one-by-one for 600 times,
  // typically 30 seconds, until they succeeded captured a |color| rectangle at
  // |rect|. This function uses |drawer|->WaitForPendingDraws() between two
  // attempts to wait for the screen to update.
  void TestCaptureOneFrame(std::vector<DesktopCapturer*> capturers,
                           ScreenDrawer* drawer,
                           DesktopRect rect,
                           RgbaColor color) {
    const int wait_capture_round = 600;
    drawer->Clear();
    size_t succeeded_capturers = 0;
    for (int i = 0; i < wait_capture_round; i++) {
      drawer->DrawRectangle(rect, color);
      drawer->WaitForPendingDraws();
      for (size_t j = 0; j < capturers.size(); j++) {
        if (capturers[j] == nullptr) {
          // DesktopCapturer should return an empty updated_region() if no
          // update detected. So we won't test it again if it has captured the
          // rectangle we drew.
          continue;
        }
        std::unique_ptr<DesktopFrame> frame = CaptureFrame(capturers[j]);
        if (!frame) {
          // CaptureFrame() has triggered an assertion failure already, we only
          // need to return here.
          return;
        }

        if (ArePixelsColoredBy(
            *frame, rect, color, drawer->MayDrawIncompleteShapes())) {
          capturers[j] = nullptr;
          succeeded_capturers++;
        }
        // The following else if statement is for debugging purpose only, which
        // should be removed after flaky of ScreenCapturerIntegrationTest has
        // been resolved.
        else if (i == wait_capture_round - 1) {
          std::string result;
          rtc::Base64::EncodeFromArray(frame->data(),
                                       frame->size().height() * frame->stride(),
                                       &result);
          std::cout << frame->size().width() << " x " << frame->size().height()
                    << std::endl;
          // Split the entire string (can be over 4M) into several lines to
          // avoid browser from sticking.
          static const size_t kLineLength = 32768;
          const char* result_end = result.c_str() + result.length();
          for (const char* it = result.c_str();
               it < result_end;
               it += kLineLength) {
            const size_t max_length = result_end - it;
            std::cout << std::string(it, std::min(kLineLength, max_length))
                      << std::endl;
          }
          std::cout << "Failed to capture rectangle " << rect.left() << " x "
                    << rect.top() << " - " << rect.right() << " x "
                    << rect.bottom() << " with color ("
                    << static_cast<int>(color.red) << ", "
                    << static_cast<int>(color.green) << ", "
                    << static_cast<int>(color.blue) << ", "
                    << static_cast<int>(color.alpha) << ")" << std::endl;
          ASSERT_TRUE(false) << "ScreenCapturerIntegrationTest may be flaky. "
                                "Please kindly FYI the broken link to "
                                "zijiehe@chromium.org for investigation. If "
                                "the failure continually happens, but I have "
                                "not responded as quick as expected, disable "
                                "*all* tests in "
                                "screen_capturer_integration_test.cc to "
                                "unblock other developers.";
        }
      }

      if (succeeded_capturers == capturers.size()) {
        break;
      }
    }

    ASSERT_EQ(succeeded_capturers, capturers.size());
  }

  // Expects |capturer| to successfully capture a frame, and returns it.
  std::unique_ptr<DesktopFrame> CaptureFrame(DesktopCapturer* capturer) {
    for (int i = 0; i < 10; i++) {
      std::unique_ptr<DesktopFrame> frame;
      DesktopCapturer::Result result;
      EXPECT_CALL(callback_, OnCaptureResultPtr(_, _))
          .WillOnce(SaveCaptureResult(&result, &frame));
      capturer->CaptureFrame();
      testing::Mock::VerifyAndClearExpectations(&callback_);
      if (result == DesktopCapturer::Result::SUCCESS) {
        EXPECT_TRUE(frame);
        return frame;
      } else {
        EXPECT_FALSE(frame);
      }
    }

    EXPECT_TRUE(false);
    return nullptr;
  }
};

#if defined(WEBRTC_WIN)
// ScreenCapturerWinGdi randomly returns blank screen, the root cause is still
// unknown. Bug, https://bugs.chromium.org/p/webrtc/issues/detail?id=6843.
#define MAYBE_CaptureUpdatedRegion DISABLED_CaptureUpdatedRegion
#else
#define MAYBE_CaptureUpdatedRegion CaptureUpdatedRegion
#endif
TEST_F(ScreenCapturerIntegrationTest, MAYBE_CaptureUpdatedRegion) {
  TestCaptureUpdatedRegion();
}

#if defined(WEBRTC_WIN)
// ScreenCapturerWinGdi randomly returns blank screen, the root cause is still
// unknown. Bug, https://bugs.chromium.org/p/webrtc/issues/detail?id=6843.
#define MAYBE_TwoCapturers DISABLED_TwoCapturers
#else
#define MAYBE_TwoCapturers TwoCapturers
#endif
TEST_F(ScreenCapturerIntegrationTest, MAYBE_TwoCapturers) {
  std::unique_ptr<DesktopCapturer> capturer2 = std::move(capturer_);
  SetUp();
  TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()});
}

#if defined(WEBRTC_WIN)

// Windows cannot capture contents on VMs hosted in GCE. See bug
// https://bugs.chromium.org/p/webrtc/issues/detail?id=8153.
TEST_F(ScreenCapturerIntegrationTest,
       DISABLED_CaptureUpdatedRegionWithDirectxCapturer) {
  if (!CreateDirectxCapturer()) {
    return;
  }

  TestCaptureUpdatedRegion();
}

TEST_F(ScreenCapturerIntegrationTest, DISABLED_TwoDirectxCapturers) {
  if (!CreateDirectxCapturer()) {
    return;
  }

  std::unique_ptr<DesktopCapturer> capturer2 = std::move(capturer_);
  RTC_CHECK(CreateDirectxCapturer());
  TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()});
}

TEST_F(ScreenCapturerIntegrationTest,
       DISABLED_CaptureUpdatedRegionWithMagnifierCapturer) {
  // On Windows 8 or later, magnifier APIs return a frame with a border on test
  // environment, so disable these tests.
  // Bug https://bugs.chromium.org/p/webrtc/issues/detail?id=6844
  // TODO(zijiehe): Find the root cause of the border and failure, which cannot
  // reproduce on my dev machine.
  if (rtc::IsWindows8OrLater()) {
    return;
  }
  CreateMagnifierCapturer();
  TestCaptureUpdatedRegion();
}

TEST_F(ScreenCapturerIntegrationTest, DISABLED_TwoMagnifierCapturers) {
  // On Windows 8 or later, magnifier APIs return a frame with a border on test
  // environment, so disable these tests.
  // Bug https://bugs.chromium.org/p/webrtc/issues/detail?id=6844
  // TODO(zijiehe): Find the root cause of the border and failure, which cannot
  // reproduce on my dev machine.
  if (rtc::IsWindows8OrLater()) {
    return;
  }
  CreateMagnifierCapturer();
  std::unique_ptr<DesktopCapturer> capturer2 = std::move(capturer_);
  CreateMagnifierCapturer();
  TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()});
}

TEST_F(ScreenCapturerIntegrationTest,
       DISABLED_MaybeCaptureUpdatedRegionWithDirectxCapturer) {
  if (!rtc::IsWindows8OrLater()) {
    // ScreenCapturerWinGdi randomly returns blank screen, the root cause is
    // still unknown. Bug,
    // https://bugs.chromium.org/p/webrtc/issues/detail?id=6843.
    // On Windows 7 or early version, MaybeCreateDirectxCapturer() always
    // creates GDI capturer.
    return;
  }
  // Even DirectX capturer is not supported in current system, we should be able
  // to select a usable capturer.
  MaybeCreateDirectxCapturer();
  TestCaptureUpdatedRegion();
}

#endif  // defined(WEBRTC_WIN)

}  // namespace webrtc
