// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/display/screen.h"

#include <utility>

#include "base/check.h"
#include "base/containers/contains.h"
#include "base/memory/ptr_util.h"
#include "base/notreached.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "ui/display/display.h"
#include "ui/display/display_util.h"
#include "ui/display/tablet_state.h"
#include "ui/display/types/display_constants.h"
#include "ui/gfx/geometry/rect.h"

namespace display {

namespace {

Screen* g_screen;

}  // namespace

Screen::Screen() : display_id_for_new_windows_(kInvalidDisplayId) {}

Screen::~Screen() = default;

// static
Screen* Screen::GetScreen() {
#if BUILDFLAG(IS_IOS)
  if (!g_screen)
    g_screen = CreateNativeScreen();
#endif
  return g_screen;
}

// static
Screen* Screen::SetScreenInstance(Screen* instance,
                                  const base::Location& location) {
  // Do not allow screen instance override. The screen object has a lot of
  // states, such as current display settings as well as observers, and safely
  // transferring these to new screen implementation is very difficult and not
  // safe.  If you hit the DCHECK in a test, please look for other examples that
  // that set a test screen instance in the setup process.
  DCHECK(!g_screen || !instance || (instance && instance->shutdown_))
      << "fail=" << location.ToString();
  return std::exchange(g_screen, instance);
}

// static
bool Screen::HasScreen() {
  return !!g_screen;
}

void Screen::SetCursorScreenPointForTesting(const gfx::Point& point) {
  NOTIMPLEMENTED_LOG_ONCE();
}

Display Screen::GetDisplayNearestView(gfx::NativeView view) const {
  return GetDisplayNearestWindow(GetWindowForView(view));
}

Display Screen::GetDisplayForNewWindows() const {
  Display display;
  // Scoped value can override if it is set.
  if (scoped_display_id_for_new_windows_ != kInvalidDisplayId &&
      GetDisplayWithDisplayId(scoped_display_id_for_new_windows_, &display)) {
    return display;
  }

  if (GetDisplayWithDisplayId(display_id_for_new_windows_, &display))
    return display;

  // Fallback to primary display.
  return GetPrimaryDisplay();
}

void Screen::SetDisplayForNewWindows(int64_t display_id) {
  // GetDisplayForNewWindows() handles invalid display ids.
  display_id_for_new_windows_ = display_id;
}

#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
Screen::ScreenSaverSuspender::~ScreenSaverSuspender() = default;

std::unique_ptr<Screen::ScreenSaverSuspender> Screen::SuspendScreenSaver() {
  NOTIMPLEMENTED_LOG_ONCE();
  return nullptr;
}
#endif  // BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)

bool Screen::IsScreenSaverActive() const {
  NOTIMPLEMENTED_LOG_ONCE();
  return false;
}

base::TimeDelta Screen::CalculateIdleTime() const {
  NOTIMPLEMENTED_LOG_ONCE();
  return base::Seconds(0);
}

gfx::Rect Screen::ScreenToDIPRectInWindow(gfx::NativeWindow window,
                                          const gfx::Rect& screen_rect) const {
  float scale = GetDisplayNearestWindow(window).device_scale_factor();
  return ScaleToEnclosingRect(screen_rect, 1.0f / scale);
}

gfx::Rect Screen::DIPToScreenRectInWindow(gfx::NativeWindow window,
                                          const gfx::Rect& dip_rect) const {
  float scale = GetDisplayNearestWindow(window).device_scale_factor();
  return ScaleToEnclosingRect(dip_rect, scale);
}

bool Screen::GetDisplayWithDisplayId(int64_t display_id,
                                     Display* display) const {
  for (const Display& display_in_list : GetAllDisplays()) {
    if (display_in_list.id() == display_id) {
      *display = display_in_list;
      return true;
    }
  }
  return false;
}

void Screen::SetPanelRotationForTesting(int64_t display_id,
                                        Display::Rotation rotation) {
  // Not implemented.
  DCHECK(false);
}

std::string Screen::GetCurrentWorkspace() {
  NOTIMPLEMENTED_LOG_ONCE();
  return {};
}

base::Value::List Screen::GetGpuExtraInfo(
    const gfx::GpuExtraInfo& gpu_extra_info) {
  return base::Value::List();
}

#if BUILDFLAG(IS_CHROMEOS)
TabletState Screen::GetTabletState() const {
  return TabletState::kInClamshellMode;
}

bool Screen::InTabletMode() const {
  TabletState state = GetTabletState();
  return state == TabletState::kInTabletMode ||
         state == TabletState::kEnteringTabletMode;
}
#endif

void Screen::SetScopedDisplayForNewWindows(int64_t display_id) {
  if (display_id == scoped_display_id_for_new_windows_)
    return;
  // Only allow set and clear, not switch.
  DCHECK(display_id == kInvalidDisplayId ^
         scoped_display_id_for_new_windows_ == kInvalidDisplayId)
      << "display_id=" << display_id << ", scoped_display_id_for_new_windows_="
      << scoped_display_id_for_new_windows_;
  scoped_display_id_for_new_windows_ = display_id;
}

ScreenInfos Screen::GetScreenInfosNearestDisplay(int64_t nearest_id) const {
  ScreenInfos result;

  // Determine the current and primary display ids.
  std::vector<Display> displays = GetAllDisplays();
  Display primary = GetPrimaryDisplay();
  // Note: displays being empty can happen in Fuchsia unit tests.
  if (displays.empty()) {
    if (primary.id() == kInvalidDisplayId) {
      // If we are in a situation where we have no displays and so the primary
      // display is invalid, then it's a logic error (elsewhere) to pass in a
      // valid id, because where would it come from?
      DCHECK_EQ(nearest_id, kInvalidDisplayId);
      primary.set_id(kDefaultDisplayId);
    }
    displays = {primary};
  }

  // Use the primary and nearest displays as fallbacks for each other, if the
  // counterpart exists in `displays`. Otherwise, use `display[0]` for both.
  int64_t primary_id = primary.id();
  int64_t current_id = nearest_id;
  const bool has_primary = base::Contains(displays, primary_id, &Display::id);
  const bool has_nearest = base::Contains(displays, nearest_id, &Display::id);
  if (!has_primary)
    primary_id = has_nearest ? nearest_id : displays[0].id();
  if (!has_nearest)
    current_id = primary_id;

  // Build ScreenInfos from discovered ids and set of all displays.
  bool current_display_exists = false;
  bool primary_display_exists = false;
  for (const auto& display : displays) {
    ScreenInfo screen_info;
    DisplayUtil::DisplayToScreenInfo(&screen_info, display);

    if (display.id() == current_id) {
      result.current_display_id = display.id();
      current_display_exists = true;
    }

    // TODO(enne): move DisplayToScreenInfo to be a private function here,
    // so that we don't need to overwrite this.
    screen_info.is_primary = display.id() == primary_id;
    if (display.id() == primary_id)
      primary_display_exists = true;

    result.screen_infos.push_back(screen_info);
  }

  // This is a bit overkill, but verify that the logic above is correct
  // because it will cause crashes elsewhere to not have a current display.
  CHECK(current_display_exists);
  CHECK(primary_display_exists);
  return result;
}

#if BUILDFLAG(IS_APPLE)

ScopedNativeScreen::ScopedNativeScreen(const base::Location& location) {
  if (!Screen::HasScreen()) {
#if BUILDFLAG(IS_IOS)
    Screen::GetScreen();
#else
    screen_ = base::WrapUnique(CreateNativeScreen());
    Screen::SetScreenInstance(screen_.get(), location);
#endif
  }
}

ScopedNativeScreen::~ScopedNativeScreen() {
  if (screen_) {
    DCHECK_EQ(screen_.get(), Screen::GetScreen());
    Screen::SetScreenInstance(nullptr);
    screen_.reset();
  }
}

#endif

}  // namespace display
