/*
 *  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 "modules/desktop_capture/win/dxgi_duplicator_controller.h"

#include <windows.h>

#include <algorithm>
#include <string>

#include "modules/desktop_capture/desktop_capture_types.h"
#include "modules/desktop_capture/win/dxgi_frame.h"
#include "modules/desktop_capture/win/screen_capture_utils.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/sleep.h"

namespace webrtc {

// static
std::string DxgiDuplicatorController::ResultName(
    DxgiDuplicatorController::Result result) {
  switch (result) {
    case Result::SUCCEEDED:
      return "Succeeded";
    case Result::UNSUPPORTED_SESSION:
      return "Unsupported session";
    case Result::FRAME_PREPARE_FAILED:
      return "Frame preparation failed";
    case Result::INITIALIZATION_FAILED:
      return "Initialization failed";
    case Result::DUPLICATION_FAILED:
      return "Duplication failed";
    case Result::INVALID_MONITOR_ID:
      return "Invalid monitor id";
    default:
      return "Unknown error";
  }
}

// static
rtc::scoped_refptr<DxgiDuplicatorController>
DxgiDuplicatorController::Instance() {
  // The static instance won't be deleted to ensure it can be used by other
  // threads even during program exiting.
  static DxgiDuplicatorController* instance = new DxgiDuplicatorController();
  return rtc::scoped_refptr<DxgiDuplicatorController>(instance);
}

// static
bool DxgiDuplicatorController::IsCurrentSessionSupported() {
  DWORD session_id = 0;
  if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &session_id)) {
    RTC_LOG(LS_WARNING)
        << "Failed to retrieve current session Id, current binary "
           "may not have required priviledge.";
    return false;
  }
  return session_id != 0;
}

DxgiDuplicatorController::DxgiDuplicatorController() : refcount_(0) {}

void DxgiDuplicatorController::AddRef() {
  int refcount = (++refcount_);
  RTC_DCHECK(refcount > 0);
}

void DxgiDuplicatorController::Release() {
  int refcount = (--refcount_);
  RTC_DCHECK(refcount >= 0);
  if (refcount == 0) {
    RTC_LOG(LS_WARNING) << "Count of references reaches zero, "
                           "DxgiDuplicatorController will be unloaded.";
    Unload();
  }
}

bool DxgiDuplicatorController::IsSupported() {
  rtc::CritScope lock(&lock_);
  return Initialize();
}

bool DxgiDuplicatorController::RetrieveD3dInfo(D3dInfo* info) {
  bool result = false;
  {
    rtc::CritScope lock(&lock_);
    result = Initialize();
    *info = d3d_info_;
  }
  if (!result) {
    RTC_LOG(LS_WARNING) << "Failed to initialize DXGI components, the D3dInfo "
                           "retrieved may not accurate or out of date.";
  }
  return result;
}

DxgiDuplicatorController::Result DxgiDuplicatorController::Duplicate(
    DxgiFrame* frame) {
  return DoDuplicate(frame, -1);
}

DxgiDuplicatorController::Result DxgiDuplicatorController::DuplicateMonitor(
    DxgiFrame* frame,
    int monitor_id) {
  RTC_DCHECK_GE(monitor_id, 0);
  return DoDuplicate(frame, monitor_id);
}

DesktopVector DxgiDuplicatorController::dpi() {
  rtc::CritScope lock(&lock_);
  if (Initialize()) {
    return dpi_;
  }
  return DesktopVector();
}

int DxgiDuplicatorController::ScreenCount() {
  rtc::CritScope lock(&lock_);
  if (Initialize()) {
    return ScreenCountUnlocked();
  }
  return 0;
}

bool DxgiDuplicatorController::GetDeviceNames(
    std::vector<std::string>* output) {
  rtc::CritScope lock(&lock_);
  if (Initialize()) {
    GetDeviceNamesUnlocked(output);
    return true;
  }
  return false;
}

DxgiDuplicatorController::Result DxgiDuplicatorController::DoDuplicate(
    DxgiFrame* frame,
    int monitor_id) {
  RTC_DCHECK(frame);
  rtc::CritScope lock(&lock_);

  // The dxgi components and APIs do not update the screen resolution without
  // a reinitialization. So we use the GetDC() function to retrieve the screen
  // resolution to decide whether dxgi components need to be reinitialized.
  // If the screen resolution changed, it's very likely the next Duplicate()
  // function call will fail because of a missing monitor or the frame size is
  // not enough to store the output. So we reinitialize dxgi components in-place
  // to avoid a capture failure.
  // But there is no guarantee GetDC() function returns the same resolution as
  // dxgi APIs, we still rely on dxgi components to return the output frame
  // size.
  // TODO(zijiehe): Confirm whether IDXGIOutput::GetDesc() and
  // IDXGIOutputDuplication::GetDesc() can detect the resolution change without
  // reinitialization.
  if (display_configuration_monitor_.IsChanged()) {
    Deinitialize();
  }

  if (!Initialize()) {
    if (succeeded_duplications_ == 0 && !IsCurrentSessionSupported()) {
      RTC_LOG(LS_WARNING) << "Current binary is running in session 0. DXGI "
                             "components cannot be initialized.";
      return Result::UNSUPPORTED_SESSION;
    }

    // Cannot initialize COM components now, display mode may be changing.
    return Result::INITIALIZATION_FAILED;
  }

  if (!frame->Prepare(SelectedDesktopSize(monitor_id), monitor_id)) {
    return Result::FRAME_PREPARE_FAILED;
  }

  frame->frame()->mutable_updated_region()->Clear();

  if (DoDuplicateUnlocked(frame->context(), monitor_id, frame->frame())) {
    succeeded_duplications_++;
    return Result::SUCCEEDED;
  }
  if (monitor_id >= ScreenCountUnlocked()) {
    // It's a user error to provide a |monitor_id| larger than screen count. We
    // do not need to deinitialize.
    return Result::INVALID_MONITOR_ID;
  }

  // If the |monitor_id| is valid, but DoDuplicateUnlocked() failed, something
  // must be wrong from capturer APIs. We should Deinitialize().
  Deinitialize();
  return Result::DUPLICATION_FAILED;
}

void DxgiDuplicatorController::Unload() {
  rtc::CritScope lock(&lock_);
  Deinitialize();
}

void DxgiDuplicatorController::Unregister(const Context* const context) {
  rtc::CritScope lock(&lock_);
  if (ContextExpired(context)) {
    // The Context has not been setup after a recent initialization, so it
    // should not been registered in duplicators.
    return;
  }
  for (size_t i = 0; i < duplicators_.size(); i++) {
    duplicators_[i].Unregister(&context->contexts[i]);
  }
}

bool DxgiDuplicatorController::Initialize() {
  if (!duplicators_.empty()) {
    return true;
  }

  if (DoInitialize()) {
    return true;
  }
  Deinitialize();
  return false;
}

bool DxgiDuplicatorController::DoInitialize() {
  RTC_DCHECK(desktop_rect_.is_empty());
  RTC_DCHECK(duplicators_.empty());

  d3d_info_.min_feature_level = static_cast<D3D_FEATURE_LEVEL>(0);
  d3d_info_.max_feature_level = static_cast<D3D_FEATURE_LEVEL>(0);

  std::vector<D3dDevice> devices = D3dDevice::EnumDevices();
  if (devices.empty()) {
    RTC_LOG(LS_WARNING) << "No D3dDevice found.";
    return false;
  }

  for (size_t i = 0; i < devices.size(); i++) {
    D3D_FEATURE_LEVEL feature_level =
        devices[i].d3d_device()->GetFeatureLevel();
    if (d3d_info_.max_feature_level == 0 ||
        feature_level > d3d_info_.max_feature_level) {
      d3d_info_.max_feature_level = feature_level;
    }
    if (d3d_info_.min_feature_level == 0 ||
        feature_level < d3d_info_.min_feature_level) {
      d3d_info_.min_feature_level = feature_level;
    }

    DxgiAdapterDuplicator duplicator(devices[i]);
    // There may be several video cards on the system, some of them may not
    // support IDXGOutputDuplication. But they should not impact others from
    // taking effect, so we should continually try other adapters. This usually
    // happens when a non-official virtual adapter is installed on the system.
    if (!duplicator.Initialize()) {
      RTC_LOG(LS_WARNING) << "Failed to initialize DxgiAdapterDuplicator on "
                             "adapter "
                          << i;
      continue;
    }
    RTC_DCHECK(!duplicator.desktop_rect().is_empty());
    duplicators_.push_back(std::move(duplicator));

    desktop_rect_.UnionWith(duplicators_.back().desktop_rect());
  }
  TranslateRect();

  HDC hdc = GetDC(nullptr);
  // Use old DPI value if failed.
  if (hdc) {
    dpi_.set(GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY));
    ReleaseDC(nullptr, hdc);
  }

  identity_++;

  if (duplicators_.empty()) {
    RTC_LOG(LS_WARNING)
        << "Cannot initialize any DxgiAdapterDuplicator instance.";
  }

  return !duplicators_.empty();
}

void DxgiDuplicatorController::Deinitialize() {
  desktop_rect_ = DesktopRect();
  duplicators_.clear();
  display_configuration_monitor_.Reset();
}

bool DxgiDuplicatorController::ContextExpired(
    const Context* const context) const {
  RTC_DCHECK(context);
  return context->controller_id != identity_ ||
         context->contexts.size() != duplicators_.size();
}

void DxgiDuplicatorController::Setup(Context* context) {
  if (ContextExpired(context)) {
    RTC_DCHECK(context);
    context->contexts.clear();
    context->contexts.resize(duplicators_.size());
    for (size_t i = 0; i < duplicators_.size(); i++) {
      duplicators_[i].Setup(&context->contexts[i]);
    }
    context->controller_id = identity_;
  }
}

bool DxgiDuplicatorController::DoDuplicateUnlocked(Context* context,
                                                   int monitor_id,
                                                   SharedDesktopFrame* target) {
  Setup(context);

  if (!EnsureFrameCaptured(context, target)) {
    return false;
  }

  bool result = false;
  if (monitor_id < 0) {
    // Capture entire screen.
    result = DoDuplicateAll(context, target);
  } else {
    result = DoDuplicateOne(context, monitor_id, target);
  }

  if (result) {
    target->set_dpi(dpi_);
    return true;
  }

  return false;
}

bool DxgiDuplicatorController::DoDuplicateAll(Context* context,
                                              SharedDesktopFrame* target) {
  for (size_t i = 0; i < duplicators_.size(); i++) {
    if (!duplicators_[i].Duplicate(&context->contexts[i], target)) {
      return false;
    }
  }
  return true;
}

bool DxgiDuplicatorController::DoDuplicateOne(Context* context,
                                              int monitor_id,
                                              SharedDesktopFrame* target) {
  RTC_DCHECK(monitor_id >= 0);
  for (size_t i = 0; i < duplicators_.size() && i < context->contexts.size();
       i++) {
    if (monitor_id >= duplicators_[i].screen_count()) {
      monitor_id -= duplicators_[i].screen_count();
    } else {
      if (duplicators_[i].DuplicateMonitor(&context->contexts[i], monitor_id,
                                           target)) {
        target->set_top_left(duplicators_[i].ScreenRect(monitor_id).top_left());
        return true;
      }
      return false;
    }
  }
  return false;
}

int64_t DxgiDuplicatorController::GetNumFramesCaptured() const {
  int64_t min = INT64_MAX;
  for (const auto& duplicator : duplicators_) {
    min = std::min(min, duplicator.GetNumFramesCaptured());
  }

  return min;
}

DesktopSize DxgiDuplicatorController::desktop_size() const {
  return desktop_rect_.size();
}

DesktopRect DxgiDuplicatorController::ScreenRect(int id) const {
  RTC_DCHECK(id >= 0);
  for (size_t i = 0; i < duplicators_.size(); i++) {
    if (id >= duplicators_[i].screen_count()) {
      id -= duplicators_[i].screen_count();
    } else {
      return duplicators_[i].ScreenRect(id);
    }
  }
  return DesktopRect();
}

int DxgiDuplicatorController::ScreenCountUnlocked() const {
  int result = 0;
  for (auto& duplicator : duplicators_) {
    result += duplicator.screen_count();
  }
  return result;
}

void DxgiDuplicatorController::GetDeviceNamesUnlocked(
    std::vector<std::string>* output) const {
  RTC_DCHECK(output);
  for (auto& duplicator : duplicators_) {
    for (int i = 0; i < duplicator.screen_count(); i++) {
      output->push_back(duplicator.GetDeviceName(i));
    }
  }
}

DesktopSize DxgiDuplicatorController::SelectedDesktopSize(
    int monitor_id) const {
  if (monitor_id < 0) {
    return desktop_size();
  }

  return ScreenRect(monitor_id).size();
}

bool DxgiDuplicatorController::EnsureFrameCaptured(Context* context,
                                                   SharedDesktopFrame* target) {
  // On a modern system, the FPS / monitor refresh rate is usually larger than
  // or equal to 60. So 17 milliseconds is enough to capture at least one frame.
  const int64_t ms_per_frame = 17;
  // Skips the first frame to ensure a full frame refresh has happened before
  // this function returns.
  const int64_t frames_to_skip = 1;
  // The total time out milliseconds for this function. If we cannot get enough
  // frames during this time interval, this function returns false, and cause
  // the DXGI components to be reinitialized. This usually should not happen
  // unless the system is switching display mode when this function is being
  // called. 500 milliseconds should be enough for ~30 frames.
  const int64_t timeout_ms = 500;
  if (GetNumFramesCaptured() >= frames_to_skip) {
    return true;
  }

  std::unique_ptr<SharedDesktopFrame> fallback_frame;
  SharedDesktopFrame* shared_frame = nullptr;
  if (target->size().width() >= desktop_size().width() &&
      target->size().height() >= desktop_size().height()) {
    // |target| is large enough to cover entire screen, we do not need to use
    // |fallback_frame|.
    shared_frame = target;
  } else {
    fallback_frame = SharedDesktopFrame::Wrap(
        std::unique_ptr<DesktopFrame>(new BasicDesktopFrame(desktop_size())));
    shared_frame = fallback_frame.get();
  }

  const int64_t start_ms = rtc::TimeMillis();
  int64_t last_frame_start_ms = 0;
  while (GetNumFramesCaptured() < frames_to_skip) {
    if (GetNumFramesCaptured() > 0) {
      // Sleep |ms_per_frame| before capturing next frame to ensure the screen
      // has been updated by the video adapter.
      webrtc::SleepMs(ms_per_frame - (rtc::TimeMillis() - last_frame_start_ms));
    }
    last_frame_start_ms = rtc::TimeMillis();
    if (!DoDuplicateAll(context, shared_frame)) {
      return false;
    }
    if (rtc::TimeMillis() - start_ms > timeout_ms) {
      RTC_LOG(LS_ERROR) << "Failed to capture " << frames_to_skip
                        << " frames "
                           "within "
                        << timeout_ms << " milliseconds.";
      return false;
    }
  }
  return true;
}

void DxgiDuplicatorController::TranslateRect() {
  const DesktopVector position =
      DesktopVector().subtract(desktop_rect_.top_left());
  desktop_rect_.Translate(position);
  for (auto& duplicator : duplicators_) {
    duplicator.TranslateRect(position);
  }
}

}  // namespace webrtc
