// Copyright (c) 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.

#import "ui/message_center/cocoa/notification_controller.h"

#include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/skia/include/core/SkBitmap.h"
#import "ui/base/cocoa/hover_image_button.h"
#import "ui/gfx/test/ui_cocoa_test_helper.h"
#include "ui/message_center/fake_message_center.h"
#include "ui/message_center/message_center_style.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_types.h"

using base::ASCIIToUTF16;
using base::UTF8ToUTF16;

namespace {

class MockMessageCenter : public message_center::FakeMessageCenter {
 public:
  MockMessageCenter()
      : last_removed_by_user_(false),
        remove_count_(0),
        last_clicked_index_(-1) {}

  virtual void RemoveNotification(const std::string& id,
                                  bool by_user) OVERRIDE {
    last_removed_id_ = id;
    last_removed_by_user_ = by_user;
    ++remove_count_;
  }

  virtual void ClickOnNotificationButton(const std::string& id,
                                         int button_index) OVERRIDE {
    last_clicked_id_ = id;
    last_clicked_index_ = button_index;
  }

  const std::string& last_removed_id() const { return last_removed_id_; }
  bool last_removed_by_user() const { return last_removed_by_user_; }
  int remove_count() const { return remove_count_; }
  const std::string& last_clicked_id() const { return last_clicked_id_; }
  int last_clicked_index() const { return last_clicked_index_; }

 private:
  std::string last_removed_id_;
  bool last_removed_by_user_;
  int remove_count_;

  std::string last_clicked_id_;
  int last_clicked_index_;

  DISALLOW_COPY_AND_ASSIGN(MockMessageCenter);
};

}  // namespace

@implementation MCNotificationController (TestingInterface)
- (NSButton*)closeButton {
  return closeButton_.get();
}

- (NSImageView*)smallImageView {
  return smallImage_.get();
}

- (NSButton*)secondButton {
  // The buttons are in Cocoa-y-order, so the 2nd button is first.
  NSView* view = [[bottomView_ subviews] objectAtIndex:0];
  return base::mac::ObjCCastStrict<NSButton>(view);
}

- (NSArray*)bottomSubviews {
  return [bottomView_ subviews];
}

- (NSImageView*)iconView {
  return icon_.get();
}

- (NSTextView*)titleView {
  return title_.get();
}

- (NSTextView*)messageView {
  return message_.get();
}

- (NSTextView*)contextMessageView {
  return contextMessage_.get();
}

- (NSView*)listView {
  return listView_.get();
}
@end

namespace message_center {

class NotificationControllerTest : public ui::CocoaTest {
 public:
  NSImage* TestIcon() {
    return [NSImage imageNamed:NSImageNameUser];
  }

 protected:
  message_center::NotifierId DummyNotifierId() {
    return message_center::NotifierId();
  }
};

TEST_F(NotificationControllerTest, BasicLayout) {
  scoped_ptr<message_center::Notification> notification(
      new message_center::Notification(
          message_center::NOTIFICATION_TYPE_SIMPLE,
          "",
          ASCIIToUTF16("Added to circles"),
          ASCIIToUTF16("Jonathan and 5 others"),
          gfx::Image(),
          base::string16(),
          DummyNotifierId(),
          message_center::RichNotificationData(),
          NULL));
  gfx::Image testIcon([TestIcon() retain]);
  notification->set_icon(testIcon);
  notification->set_small_image(testIcon);

  base::scoped_nsobject<MCNotificationController> controller(
      [[MCNotificationController alloc] initWithNotification:notification.get()
                                               messageCenter:NULL]);
  [controller view];

  EXPECT_EQ(TestIcon(), [[controller iconView] image]);
  EXPECT_EQ(TestIcon(), [[controller smallImageView] image]);
  EXPECT_EQ(base::SysNSStringToUTF16([[controller titleView] string]),
            notification->title());
  EXPECT_EQ(base::SysNSStringToUTF16([[controller messageView] string]),
            notification->message());
  EXPECT_EQ(controller.get(), [[controller closeButton] target]);
}

TEST_F(NotificationControllerTest, OverflowText) {
  scoped_ptr<message_center::Notification> notification(
      new message_center::Notification(
          message_center::NOTIFICATION_TYPE_SIMPLE,
          "",
          ASCIIToUTF16("This is a much longer title that should wrap "
                       "multiple lines."),
          ASCIIToUTF16("And even the message is long. This sure is a wordy "
                       "notification. Are you really going to read this "
                       "entire thing?"),
          gfx::Image(),
          base::string16(),
          DummyNotifierId(),
          message_center::RichNotificationData(),
          NULL));
  base::scoped_nsobject<MCNotificationController> controller(
      [[MCNotificationController alloc] initWithNotification:notification.get()
                                               messageCenter:NULL]);
  [controller view];

  EXPECT_GT(NSHeight([[controller view] frame]),
            message_center::kNotificationIconSize);
}

TEST_F(NotificationControllerTest, Close) {
  scoped_ptr<message_center::Notification> notification(
      new message_center::Notification(
          message_center::NOTIFICATION_TYPE_SIMPLE,
          "an_id",
          base::string16(),
          base::string16(),
          gfx::Image(),
          base::string16(),
          DummyNotifierId(),
          message_center::RichNotificationData(),
          NULL));
  MockMessageCenter message_center;

  base::scoped_nsobject<MCNotificationController> controller(
      [[MCNotificationController alloc] initWithNotification:notification.get()
                                               messageCenter:&message_center]);
  [controller view];

  [[controller closeButton] performClick:nil];

  EXPECT_EQ(1, message_center.remove_count());
  EXPECT_EQ("an_id", message_center.last_removed_id());
  EXPECT_TRUE(message_center.last_removed_by_user());
}

TEST_F(NotificationControllerTest, Update) {
  scoped_ptr<message_center::Notification> notification(
      new message_center::Notification(
          message_center::NOTIFICATION_TYPE_SIMPLE,
          "",
          ASCIIToUTF16("A simple title"),
          ASCIIToUTF16("This message isn't too long and should fit in the"
                       "default bounds."),
          gfx::Image(),
          base::string16(),
          DummyNotifierId(),
          message_center::RichNotificationData(),
          NULL));
  base::scoped_nsobject<MCNotificationController> controller(
      [[MCNotificationController alloc] initWithNotification:notification.get()
                                               messageCenter:NULL]);

  // Set up the default layout.
  [controller view];
  EXPECT_EQ(NSHeight([[controller view] frame]),
            message_center::kNotificationIconSize);
  EXPECT_FALSE([[controller iconView] image]);
  EXPECT_FALSE([[controller smallImageView] image]);

  // Update the icon.
  gfx::Image testIcon([TestIcon() retain]);
  notification->set_icon(testIcon);
  notification->set_small_image(testIcon);
  [controller updateNotification:notification.get()];
  EXPECT_EQ(TestIcon(), [[controller iconView] image]);
  EXPECT_EQ(TestIcon(), [[controller smallImageView] image]);
  EXPECT_EQ(NSHeight([[controller view] frame]),
            message_center::kNotificationIconSize);
}

TEST_F(NotificationControllerTest, Buttons) {
  message_center::RichNotificationData optional;
  message_center::ButtonInfo button1(UTF8ToUTF16("button1"));
  optional.buttons.push_back(button1);
  message_center::ButtonInfo button2(UTF8ToUTF16("button2"));
  optional.buttons.push_back(button2);

  scoped_ptr<message_center::Notification> notification(
      new message_center::Notification(
          message_center::NOTIFICATION_TYPE_BASE_FORMAT,
          "an_id",
          base::string16(),
          base::string16(),
          gfx::Image(),
          base::string16(),
          DummyNotifierId(),
          optional,
          NULL));
  MockMessageCenter message_center;

  base::scoped_nsobject<MCNotificationController> controller(
      [[MCNotificationController alloc] initWithNotification:notification.get()
                                               messageCenter:&message_center]);
  [controller view];

  [[controller secondButton] performClick:nil];

  EXPECT_EQ("an_id", message_center.last_clicked_id());
  EXPECT_EQ(1, message_center.last_clicked_index());
}

TEST_F(NotificationControllerTest, Image) {
  scoped_ptr<message_center::Notification> notification(
      new message_center::Notification(
          message_center::NOTIFICATION_TYPE_BASE_FORMAT,
          "an_id",
          base::string16(),
          base::string16(),
          gfx::Image(),
          base::string16(),
          DummyNotifierId(),
          message_center::RichNotificationData(),
          NULL));
  NSImage* image = [NSImage imageNamed:NSImageNameFolder];
  notification->set_image(gfx::Image([image retain]));

  MockMessageCenter message_center;

  base::scoped_nsobject<MCNotificationController> controller(
      [[MCNotificationController alloc] initWithNotification:notification.get()
                                               messageCenter:&message_center]);
  [controller view];

  ASSERT_EQ(1u, [[controller bottomSubviews] count]);
  ASSERT_TRUE([[[[controller bottomSubviews] lastObject] contentView]
      isKindOfClass:[NSImageView class]]);
  EXPECT_EQ(image,
      [[[[controller bottomSubviews] lastObject] contentView] image]);
}

TEST_F(NotificationControllerTest, List) {
  message_center::RichNotificationData optional;
  message_center::NotificationItem item1(
      UTF8ToUTF16("First title"), UTF8ToUTF16("first message"));
  optional.items.push_back(item1);
  message_center::NotificationItem item2(
      UTF8ToUTF16("Second title"),
      UTF8ToUTF16("second slightly longer message"));
  optional.items.push_back(item2);
  message_center::NotificationItem item3(
      UTF8ToUTF16(""),    // Test for empty string.
      UTF8ToUTF16(" "));  // Test for string containing only spaces.
  optional.items.push_back(item3);
  optional.context_message = UTF8ToUTF16("Context Message");

  scoped_ptr<message_center::Notification> notification(
      new message_center::Notification(
          message_center::NOTIFICATION_TYPE_BASE_FORMAT,
          "an_id",
          UTF8ToUTF16("Notification Title"),
          UTF8ToUTF16("Notification Message - should be hidden"),
          gfx::Image(),
          base::string16(),
          DummyNotifierId(),
          optional,
          NULL));

  MockMessageCenter message_center;
  base::scoped_nsobject<MCNotificationController> controller(
      [[MCNotificationController alloc] initWithNotification:notification.get()
                                               messageCenter:&message_center]);
  [controller view];

  EXPECT_FALSE([[controller titleView] isHidden]);
  EXPECT_TRUE([[controller messageView] isHidden]);
  EXPECT_FALSE([[controller contextMessageView] isHidden]);

  EXPECT_EQ(3u, [[[controller listView] subviews] count]);
  EXPECT_LT(NSMaxY([[controller listView] frame]),
            NSMinY([[controller titleView] frame]));
}

TEST_F(NotificationControllerTest, NoMessage) {
  message_center::RichNotificationData optional;
  optional.context_message = UTF8ToUTF16("Context Message");

  scoped_ptr<message_center::Notification> notification(
      new message_center::Notification(
          message_center::NOTIFICATION_TYPE_BASE_FORMAT,
          "an_id",
          UTF8ToUTF16("Notification Title"),
          UTF8ToUTF16(""),
          gfx::Image(),
          base::string16(),
          DummyNotifierId(),
          optional,
          NULL));

  MockMessageCenter message_center;
  base::scoped_nsobject<MCNotificationController> controller(
      [[MCNotificationController alloc] initWithNotification:notification.get()
                                               messageCenter:&message_center]);
  [controller view];

  EXPECT_FALSE([[controller titleView] isHidden]);
  EXPECT_TRUE([[controller messageView] isHidden]);
  EXPECT_FALSE([[controller contextMessageView] isHidden]);
}

TEST_F(NotificationControllerTest, MessageSize) {
  message_center::RichNotificationData data;
  std::string id("id");
  NotifierId notifier_id(NotifierId::APPLICATION, "notifier");
  scoped_ptr<Notification> notification(new Notification(
      NOTIFICATION_TYPE_BASE_FORMAT,
      id,
      base::UTF8ToUTF16(""),
      ASCIIToUTF16("And\neven\nthe\nmessage is long.\nThis sure is wordy"),
      gfx::Image(),
      base::string16() /* display_source */,
      notifier_id,
      data,
      NULL /* delegate */));

  base::scoped_nsobject<MCNotificationController> controller(
      [[MCNotificationController alloc] initWithNotification:notification.get()
                                               messageCenter:NULL]);

  // Set up the default layout.
  [controller view];

  auto compute_message_lines = ^{
      NSString* string = [[[controller messageView] textStorage] string];
      unsigned numberOfLines, index, stringLength = [string length];
      for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++)
        index = NSMaxRange([string lineRangeForRange:NSMakeRange(index, 0)]);

      return numberOfLines;
  };

  // Message and no title: 5 lines.
  EXPECT_EQ(5u, compute_message_lines());

  // Message and one line title: 5 lines.
  notification->set_title(ASCIIToUTF16("one line"));
  [controller updateNotification:notification.get()];
  EXPECT_EQ(5u, compute_message_lines());

  // Message and two line title: 3 lines.
  notification->set_title(ASCIIToUTF16("two\nlines"));
  [controller updateNotification:notification.get()];
  EXPECT_EQ(3u, compute_message_lines());

  // Message, image and no title: 2 lines.
  SkBitmap bitmap;
  bitmap.allocN32Pixels(2, 2);
  bitmap.eraseColor(SK_ColorGREEN);
  notification->set_title(ASCIIToUTF16(""));
  notification->set_image(gfx::Image::CreateFrom1xBitmap(bitmap));
  [controller updateNotification:notification.get()];
  EXPECT_EQ(2u, compute_message_lines());

  // Message, image and one line title: 2 lines.
  notification->set_title(ASCIIToUTF16("one line"));
  [controller updateNotification:notification.get()];
  EXPECT_EQ(2u, compute_message_lines());

  // Message, image and two line title: 1 lines.
  notification->set_title(ASCIIToUTF16("two\nlines"));
  [controller updateNotification:notification.get()];
  EXPECT_EQ(1u, compute_message_lines());

  // Same as above, but context message takes away from message lines.
  notification->set_context_message(base::UTF8ToUTF16("foo"));
  notification->set_title(ASCIIToUTF16(""));
  [controller updateNotification:notification.get()];
  EXPECT_EQ(1u, compute_message_lines());

  notification->set_title(ASCIIToUTF16("one line"));
  [controller updateNotification:notification.get()];
  EXPECT_EQ(1u, compute_message_lines());

  notification->set_title(ASCIIToUTF16("two\nlines"));
  [controller updateNotification:notification.get()];
  EXPECT_EQ(0u, compute_message_lines());
}

}  // namespace message_center
