// Copyright 2014 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 "ui/display/display_change_notifier.h"

#include <stdint.h>

#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/display.h"
#include "ui/display/display_observer.h"

namespace display {

class MockDisplayObserver : public DisplayObserver {
 public:
  MockDisplayObserver()
      : display_added_(0),
        display_removed_(0),
        display_changed_(0),
        latest_metrics_change_(DisplayObserver::DISPLAY_METRIC_NONE) {}

  ~MockDisplayObserver() override {}

  void OnDisplayAdded(const Display& display) override { display_added_++; }

  void OnDisplayRemoved(const Display& display) override { display_removed_++; }

  void OnDisplayMetricsChanged(const Display& display,
                               uint32_t metrics) override {
    display_changed_++;
    latest_metrics_change_ = metrics;
  }

  int display_added() const { return display_added_; }

  int display_removed() const { return display_removed_; }

  int display_changed() const { return display_changed_; }

  uint32_t latest_metrics_change() const { return latest_metrics_change_; }

 protected:
  int display_added_;
  int display_removed_;
  int display_changed_;
  uint32_t latest_metrics_change_;

  DISALLOW_COPY_AND_ASSIGN(MockDisplayObserver);
};

TEST(DisplayChangeNotifierTest, AddObserver_Smoke) {
  DisplayChangeNotifier change_notifier;
  MockDisplayObserver observer;

  change_notifier.NotifyDisplaysChanged(std::vector<Display>(),
                                        std::vector<Display>(1, Display()));
  EXPECT_EQ(0, observer.display_added());

  change_notifier.AddObserver(&observer);
  change_notifier.NotifyDisplaysChanged(std::vector<Display>(),
                                        std::vector<Display>(1, Display()));
  EXPECT_EQ(1, observer.display_added());
}

TEST(DisplayChangeNotifier, RemoveObserver_Smoke) {
  DisplayChangeNotifier change_notifier;
  MockDisplayObserver observer;

  change_notifier.NotifyDisplaysChanged(std::vector<Display>(),
                                        std::vector<Display>(1, Display()));
  EXPECT_EQ(0, observer.display_added());

  change_notifier.AddObserver(&observer);
  change_notifier.RemoveObserver(&observer);

  change_notifier.NotifyDisplaysChanged(std::vector<Display>(),
                                        std::vector<Display>(1, Display()));
  EXPECT_EQ(0, observer.display_added());
}

TEST(DisplayChangeNotifierTest, RemoveObserver_Unknown) {
  DisplayChangeNotifier change_notifier;
  MockDisplayObserver observer;

  change_notifier.RemoveObserver(&observer);
  // Should not crash.
}

TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Removed) {
  DisplayChangeNotifier change_notifier;

  // If the previous display array is empty, no removal.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    new_displays.push_back(Display());

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_removed());

    change_notifier.RemoveObserver(&observer);
  }

  // If the previous and new display array are empty, no removal.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_removed());

    change_notifier.RemoveObserver(&observer);
  }

  // If the new display array is empty, there are as many removal as old
  // displays.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display());
    old_displays.push_back(Display());
    old_displays.push_back(Display());

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(3, observer.display_removed());

    change_notifier.RemoveObserver(&observer);
  }

  // If displays don't use ids, as long as the new display array has one
  // element, there are no removals.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display());
    old_displays.push_back(Display());
    old_displays.push_back(Display());
    new_displays.push_back(Display());

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_removed());

    change_notifier.RemoveObserver(&observer);
  }

  // If displays use ids (and they are unique), ids not present in the new
  // display array will be marked as removed.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display(1));
    old_displays.push_back(Display(2));
    old_displays.push_back(Display(3));
    new_displays.push_back(Display(2));

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(2, observer.display_removed());

    change_notifier.RemoveObserver(&observer);
  }
}

TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Added) {
  DisplayChangeNotifier change_notifier;

  // If the new display array is empty, no addition.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display());

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_added());

    change_notifier.RemoveObserver(&observer);
  }

  // If the old and new display arrays are empty, no addition.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_added());

    change_notifier.RemoveObserver(&observer);
  }

  // If the old display array is empty, there are as many addition as new
  // displays.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    new_displays.push_back(Display());
    new_displays.push_back(Display());
    new_displays.push_back(Display());

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(3, observer.display_added());

    change_notifier.RemoveObserver(&observer);
  }

  // If displays don't use ids, as long as the old display array has one
  // element, there are no additions.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display());
    new_displays.push_back(Display());
    new_displays.push_back(Display());
    new_displays.push_back(Display());

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_added());

    change_notifier.RemoveObserver(&observer);
  }

  // If displays use ids (and they are unique), ids not present in the old
  // display array will be marked as added.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display(1));
    new_displays.push_back(Display(1));
    new_displays.push_back(Display(2));
    new_displays.push_back(Display(3));

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(2, observer.display_added());

    change_notifier.RemoveObserver(&observer);
  }
}

TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Smoke) {
  DisplayChangeNotifier change_notifier;

  // If the old display array is empty, no change.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    new_displays.push_back(Display());

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_changed());

    change_notifier.RemoveObserver(&observer);
  }

  // If the new display array is empty, no change.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display());

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_changed());

    change_notifier.RemoveObserver(&observer);
  }

  // If the old and new display arrays are empty, no change.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_changed());

    change_notifier.RemoveObserver(&observer);
  }

  // If there is an intersection between old and new displays but there are no
  // metrics changes, there is no display change.
  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display(1));
    new_displays.push_back(Display(1));
    new_displays.push_back(Display(2));
    new_displays.push_back(Display(3));

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_changed());

    change_notifier.RemoveObserver(&observer);
  }
}

TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Bounds) {
  DisplayChangeNotifier change_notifier;

  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display(1, gfx::Rect(0, 0, 200, 200)));
    new_displays.push_back(Display(1, gfx::Rect(0, 0, 200, 200)));

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(0, observer.display_changed());

    change_notifier.RemoveObserver(&observer);
  }

  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display(1, gfx::Rect(0, 0, 200, 200)));
    new_displays.push_back(Display(1, gfx::Rect(10, 10, 300, 300)));

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(1, observer.display_changed());
    uint32_t metrics_change = DisplayObserver::DISPLAY_METRIC_BOUNDS |
                              DisplayObserver::DISPLAY_METRIC_WORK_AREA;
    EXPECT_EQ(metrics_change, observer.latest_metrics_change());

    change_notifier.RemoveObserver(&observer);
  }

  {
    MockDisplayObserver observer;
    change_notifier.AddObserver(&observer);

    std::vector<Display> old_displays, new_displays;
    old_displays.push_back(Display(1, gfx::Rect(0, 0, 200, 200)));
    new_displays.push_back(Display(1, gfx::Rect(0, 0, 200, 200)));
    new_displays[0].set_bounds(gfx::Rect(10, 10, 300, 300));

    change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
    EXPECT_EQ(1, observer.display_changed());
    EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_BOUNDS,
              observer.latest_metrics_change());

    change_notifier.RemoveObserver(&observer);
  }
}

TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Rotation) {
  DisplayChangeNotifier change_notifier;
  MockDisplayObserver observer;
  change_notifier.AddObserver(&observer);

  std::vector<Display> old_displays, new_displays;
  old_displays.push_back(Display(1));
  old_displays[0].SetRotationAsDegree(0);
  new_displays.push_back(Display(1));
  new_displays[0].SetRotationAsDegree(180);

  change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
  EXPECT_EQ(1, observer.display_changed());
  EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_ROTATION,
            observer.latest_metrics_change());
}

TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_WorkArea) {
  DisplayChangeNotifier change_notifier;
  MockDisplayObserver observer;
  change_notifier.AddObserver(&observer);

  std::vector<Display> old_displays, new_displays;
  old_displays.push_back(Display(1));
  old_displays[0].set_work_area(gfx::Rect(0, 0, 200, 200));
  new_displays.push_back(Display(1));
  new_displays[0].set_work_area(gfx::Rect(20, 20, 300, 300));

  change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
  EXPECT_EQ(1, observer.display_changed());
  EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_WORK_AREA,
            observer.latest_metrics_change());
}

TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_DSF) {
  DisplayChangeNotifier change_notifier;
  MockDisplayObserver observer;
  change_notifier.AddObserver(&observer);

  std::vector<Display> old_displays, new_displays;
  old_displays.push_back(Display(1));
  old_displays[0].set_device_scale_factor(1.f);
  new_displays.push_back(Display(1));
  new_displays[0].set_device_scale_factor(2.f);

  change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
  EXPECT_EQ(1, observer.display_changed());
  EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR,
            observer.latest_metrics_change());
}

TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Multi_Displays) {
  DisplayChangeNotifier change_notifier;
  MockDisplayObserver observer;
  change_notifier.AddObserver(&observer);

  std::vector<Display> old_displays, new_displays;
  old_displays.push_back(Display(1));
  old_displays.push_back(Display(2));
  old_displays.push_back(Display(3));
  new_displays.push_back(Display(1));
  new_displays.push_back(Display(2));
  new_displays.push_back(Display(3));

  old_displays[0].set_device_scale_factor(1.f);
  new_displays[0].set_device_scale_factor(2.f);

  old_displays[1].set_bounds(gfx::Rect(0, 0, 200, 200));
  new_displays[1].set_bounds(gfx::Rect(0, 0, 400, 400));

  old_displays[2].SetRotationAsDegree(0);
  new_displays[2].SetRotationAsDegree(90);

  change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
  EXPECT_EQ(3, observer.display_changed());
}

TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Multi_Metrics) {
  DisplayChangeNotifier change_notifier;
  MockDisplayObserver observer;
  change_notifier.AddObserver(&observer);

  std::vector<Display> old_displays, new_displays;
  old_displays.push_back(Display(1, gfx::Rect(0, 0, 200, 200)));
  old_displays[0].set_device_scale_factor(1.f);
  old_displays[0].SetRotationAsDegree(0);

  new_displays.push_back(Display(1, gfx::Rect(100, 100, 200, 200)));
  new_displays[0].set_device_scale_factor(2.f);
  new_displays[0].SetRotationAsDegree(90);

  change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
  EXPECT_EQ(1, observer.display_changed());
  uint32_t metrics = DisplayObserver::DISPLAY_METRIC_BOUNDS |
                     DisplayObserver::DISPLAY_METRIC_ROTATION |
                     DisplayObserver::DISPLAY_METRIC_WORK_AREA |
                     DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
  EXPECT_EQ(metrics, observer.latest_metrics_change());
}

}  // namespace display
