// Copyright 2013 The Chromium 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 "ash/display/resolution_notification_controller.h"

#include "ash/display/display_manager.h"
#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/size.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_list.h"

namespace ash {
namespace {

base::string16 ExpectedNotificationMessage(int64 display_id,
                                           const gfx::Size& new_resolution) {
  return l10n_util::GetStringFUTF16(
      IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
      base::UTF8ToUTF16(
          Shell::GetInstance()->display_manager()->GetDisplayNameForId(
              display_id)),
      base::UTF8ToUTF16(new_resolution.ToString()));
}

base::string16 ExpectedFallbackNotificationMessage(
    int64 display_id,
    const gfx::Size& specified_resolution,
    const gfx::Size& fallback_resolution) {
  return l10n_util::GetStringFUTF16(
      IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED_TO_UNSUPPORTED,
      base::UTF8ToUTF16(
          Shell::GetInstance()->display_manager()->GetDisplayNameForId(
              display_id)),
      base::UTF8ToUTF16(specified_resolution.ToString()),
      base::UTF8ToUTF16(fallback_resolution.ToString()));
}

}  // namespace

class ResolutionNotificationControllerTest : public ash::test::AshTestBase {
 public:
  ResolutionNotificationControllerTest()
      : accept_count_(0) {
  }

  virtual ~ResolutionNotificationControllerTest() {}

 protected:
  virtual void SetUp() OVERRIDE {
    ash::test::AshTestBase::SetUp();
    ResolutionNotificationController::SuppressTimerForTest();
  }

  void SetDisplayResolutionAndNotifyWithResolution(
      const gfx::Display& display,
      const gfx::Size& new_resolution,
      const gfx::Size& actual_new_resolution) {
    DisplayManager* display_manager = Shell::GetInstance()->display_manager();
    const DisplayInfo& info = display_manager->GetDisplayInfo(display.id());
    controller()->SetDisplayResolutionAndNotify(
        display.id(),
        info.size_in_pixel(),
        new_resolution,
        base::Bind(&ResolutionNotificationControllerTest::OnAccepted,
                   base::Unretained(this)));

    // OnConfigurationChanged event won't be emitted in the test environment,
    // so invoke UpdateDisplay() to emit that event explicitly.
    std::vector<DisplayInfo> info_list;
    for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
      int64 id = display_manager->GetDisplayAt(i).id();
      DisplayInfo info = display_manager->GetDisplayInfo(id);
      if (display.id() == id) {
        gfx::Rect bounds = info.bounds_in_native();
        bounds.set_size(actual_new_resolution);
        info.SetBounds(bounds);
      }
      info_list.push_back(info);
    }
    display_manager->OnNativeDisplaysChanged(info_list);
    RunAllPendingInMessageLoop();
  }

  void SetDisplayResolutionAndNotify(const gfx::Display& display,
                                     const gfx::Size& new_resolution) {
    SetDisplayResolutionAndNotifyWithResolution(
        display, new_resolution, new_resolution);
  }

  static base::string16 GetNotificationMessage() {
    const message_center::NotificationList::Notifications& notifications =
        message_center::MessageCenter::Get()->GetVisibleNotifications();
    for (message_center::NotificationList::Notifications::const_iterator iter =
             notifications.begin(); iter != notifications.end(); ++iter) {
      if ((*iter)->id() == ResolutionNotificationController::kNotificationId)
        return (*iter)->title();
    }

    return base::string16();
  }

  static void ClickOnNotification() {
    message_center::MessageCenter::Get()->ClickOnNotification(
        ResolutionNotificationController::kNotificationId);
  }

  static void ClickOnNotificationButton(int index) {
    message_center::MessageCenter::Get()->ClickOnNotificationButton(
        ResolutionNotificationController::kNotificationId, index);
  }

  static void CloseNotification() {
    message_center::MessageCenter::Get()->RemoveNotification(
        ResolutionNotificationController::kNotificationId, true /* by_user */);
  }

  static bool IsNotificationVisible() {
    return message_center::MessageCenter::Get()->FindVisibleNotificationById(
        ResolutionNotificationController::kNotificationId);
  }

  static void TickTimer() {
    controller()->OnTimerTick();
  }

  static ResolutionNotificationController* controller() {
    return Shell::GetInstance()->resolution_notification_controller();
  }

  int accept_count() const {
    return accept_count_;
  }

 private:
  void OnAccepted() {
    EXPECT_FALSE(controller()->DoesNotificationTimeout());
    accept_count_++;
  }

  int accept_count_;

  DISALLOW_COPY_AND_ASSIGN(ResolutionNotificationControllerTest);
};

// Basic behaviors and verifies it doesn't cause crashes.
TEST_F(ResolutionNotificationControllerTest, Basic) {
  if (!SupportsMultipleDisplays())
    return;

  UpdateDisplay("300x300#300x300%57|200x200%58,250x250#250x250%59|200x200%60");
  int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
  ash::DisplayManager* display_manager =
      ash::Shell::GetInstance()->display_manager();
  ASSERT_EQ(0, accept_count());
  EXPECT_FALSE(IsNotificationVisible());

  // Changes the resolution and apply the result.
  SetDisplayResolutionAndNotify(
      ScreenUtil::GetSecondaryDisplay(), gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
  EXPECT_EQ(ExpectedNotificationMessage(id2, gfx::Size(200, 200)),
            GetNotificationMessage());
  DisplayMode mode;
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size.ToString());
  EXPECT_EQ(60.0, mode.refresh_rate);

  // Click the revert button, which reverts to the best resolution.
  ClickOnNotificationButton(0);
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(0, accept_count());
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("250x250", mode.size.ToString());
  EXPECT_EQ(59.0, mode.refresh_rate);
}

TEST_F(ResolutionNotificationControllerTest, ClickMeansAccept) {
  if (!SupportsMultipleDisplays())
    return;

  UpdateDisplay("300x300#300x300%57|200x200%58,250x250#250x250%59|200x200%60");
  int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
  ash::DisplayManager* display_manager =
      ash::Shell::GetInstance()->display_manager();
  ASSERT_EQ(0, accept_count());
  EXPECT_FALSE(IsNotificationVisible());

  // Changes the resolution and apply the result.
  SetDisplayResolutionAndNotify(
      ScreenUtil::GetSecondaryDisplay(), gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
  DisplayMode mode;
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size.ToString());
  EXPECT_EQ(60.0, mode.refresh_rate);

  // Click the revert button, which reverts the resolution.
  ClickOnNotification();
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(1, accept_count());
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size.ToString());
  EXPECT_EQ(60.0, mode.refresh_rate);
}

TEST_F(ResolutionNotificationControllerTest, AcceptButton) {
  if (!SupportsMultipleDisplays())
    return;

  ash::DisplayManager* display_manager =
      ash::Shell::GetInstance()->display_manager();

  UpdateDisplay("300x300#300x300%59|200x200%60");
  const gfx::Display& display = ash::Shell::GetScreen()->GetPrimaryDisplay();
  SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());

  // If there's a single display only, it will have timeout and the first button
  // becomes accept.
  EXPECT_TRUE(controller()->DoesNotificationTimeout());
  ClickOnNotificationButton(0);
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(1, accept_count());
  DisplayMode mode;
  EXPECT_TRUE(
      display_manager->GetSelectedModeForDisplayId(display.id(), &mode));
  EXPECT_EQ("200x200", mode.size.ToString());
  EXPECT_EQ(60.0f, mode.refresh_rate);

  // In that case the second button is revert.
  UpdateDisplay("300x300#300x300%59|200x200%60");
  SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());

  EXPECT_TRUE(controller()->DoesNotificationTimeout());
  ClickOnNotificationButton(1);
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(1, accept_count());
  EXPECT_TRUE(
      display_manager->GetSelectedModeForDisplayId(display.id(), &mode));
  EXPECT_EQ("300x300", mode.size.ToString());
  EXPECT_EQ(59.0f, mode.refresh_rate);
}

TEST_F(ResolutionNotificationControllerTest, Close) {
  if (!SupportsMultipleDisplays())
    return;

  UpdateDisplay("100x100,150x150#150x150%59|200x200%60");
  int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
  ash::DisplayManager* display_manager =
      ash::Shell::GetInstance()->display_manager();
  ASSERT_EQ(0, accept_count());
  EXPECT_FALSE(IsNotificationVisible());

  // Changes the resolution and apply the result.
  SetDisplayResolutionAndNotify(
      ScreenUtil::GetSecondaryDisplay(), gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
  DisplayMode mode;
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size.ToString());
  EXPECT_EQ(60.0f, mode.refresh_rate);

  // Close the notification (imitates clicking [x] button). Also verifies if
  // this does not cause a crash.  See crbug.com/271784
  CloseNotification();
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(1, accept_count());
}

TEST_F(ResolutionNotificationControllerTest, Timeout) {
  if (!SupportsMultipleDisplays())
    return;

  UpdateDisplay("300x300#300x300%59|200x200%60");
  const gfx::Display& display = ash::Shell::GetScreen()->GetPrimaryDisplay();
  SetDisplayResolutionAndNotify(display, gfx::Size(200, 200));

  for (int i = 0; i < ResolutionNotificationController::kTimeoutInSec; ++i) {
    EXPECT_TRUE(IsNotificationVisible()) << "notification is closed after "
                                         << i << "-th timer tick";
    TickTimer();
    RunAllPendingInMessageLoop();
  }
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(0, accept_count());
  ash::DisplayManager* display_manager =
      ash::Shell::GetInstance()->display_manager();
  DisplayMode mode;
  EXPECT_TRUE(
      display_manager->GetSelectedModeForDisplayId(display.id(), &mode));
  EXPECT_EQ("300x300", mode.size.ToString());
  EXPECT_EQ(59.0f, mode.refresh_rate);
}

TEST_F(ResolutionNotificationControllerTest, DisplayDisconnected) {
  if (!SupportsMultipleDisplays())
    return;

  UpdateDisplay("300x300#300x300%56|200x200%57,"
                "200x200#250x250%58|200x200%59|100x100%60");
  int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
  ash::DisplayManager* display_manager =
      ash::Shell::GetInstance()->display_manager();
  SetDisplayResolutionAndNotify(
      ScreenUtil::GetSecondaryDisplay(), gfx::Size(100, 100));
  ASSERT_TRUE(IsNotificationVisible());

  // Disconnects the secondary display and verifies it doesn't cause crashes.
  UpdateDisplay("300x300#300x300%56|200x200%57");
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(0, accept_count());
  DisplayMode mode;
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  gfx::Size resolution;
  EXPECT_EQ("200x200", mode.size.ToString());
  EXPECT_EQ(59.0f, mode.refresh_rate);
}

TEST_F(ResolutionNotificationControllerTest, MultipleResolutionChange) {
  if (!SupportsMultipleDisplays())
    return;

  UpdateDisplay("300x300#300x300%56|200x200%57,"
                "250x250#250x250%58|200x200%59");
  int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
  ash::DisplayManager* display_manager =
      ash::Shell::GetInstance()->display_manager();

  SetDisplayResolutionAndNotify(
      ScreenUtil::GetSecondaryDisplay(), gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
  DisplayMode mode;
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size.ToString());
  EXPECT_EQ(59.0f, mode.refresh_rate);

  // Invokes SetDisplayResolutionAndNotify during the previous notification is
  // visible.
  SetDisplayResolutionAndNotify(
      ScreenUtil::GetSecondaryDisplay(), gfx::Size(250, 250));
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("250x250", mode.size.ToString());
  EXPECT_EQ(58.0f, mode.refresh_rate);

  // Then, click the revert button. Although |old_resolution| for the second
  // SetDisplayResolutionAndNotify is 200x200, it should revert to the original
  // size 250x250.
  ClickOnNotificationButton(0);
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(0, accept_count());
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("250x250", mode.size.ToString());
  EXPECT_EQ(58.0f, mode.refresh_rate);
}

TEST_F(ResolutionNotificationControllerTest, Fallback) {
  if (!SupportsMultipleDisplays())
    return;

  UpdateDisplay("300x300#300x300%56|200x200%57,"
                "250x250#250x250%58|220x220%59|200x200%60");
  int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
  ash::DisplayManager* display_manager =
      ash::Shell::GetInstance()->display_manager();
  ASSERT_EQ(0, accept_count());
  EXPECT_FALSE(IsNotificationVisible());

  // Changes the resolution and apply the result.
  SetDisplayResolutionAndNotifyWithResolution(
      ScreenUtil::GetSecondaryDisplay(),
      gfx::Size(220, 220),
      gfx::Size(200, 200));
  EXPECT_TRUE(IsNotificationVisible());
  EXPECT_FALSE(controller()->DoesNotificationTimeout());
  EXPECT_EQ(
      ExpectedFallbackNotificationMessage(
          id2, gfx::Size(220, 220), gfx::Size(200, 200)),
      GetNotificationMessage());
  DisplayMode mode;
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("200x200", mode.size.ToString());
  EXPECT_EQ(60.0f, mode.refresh_rate);

  // Click the revert button, which reverts to the best resolution.
  ClickOnNotificationButton(0);
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(IsNotificationVisible());
  EXPECT_EQ(0, accept_count());
  EXPECT_TRUE(display_manager->GetSelectedModeForDisplayId(id2, &mode));
  EXPECT_EQ("250x250", mode.size.ToString());
  EXPECT_EQ(58.0f, mode.refresh_rate);
}

}  // namespace ash
