// Copyright (c) 2011 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 "content/browser/notification_service_impl.h"

#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_types.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

namespace {

// Bogus class to act as a NotificationSource for the messages.
class TestSource {};

class TestObserver : public NotificationObserver {
 public:
  TestObserver() : notification_count_(0) {}

  int notification_count() const { return notification_count_; }

  void Observe(int type,
               const NotificationSource& source,
               const NotificationDetails& details) override {
    ++notification_count_;
  }

 private:
  int notification_count_;
};

const int kNotification1 = 1;
const int kNotification2 = 2;

}  // namespace


class NotificationServiceImplTest : public testing::Test {
 protected:
  NotificationRegistrar registrar_;
};

TEST_F(NotificationServiceImplTest, Basic) {
  TestSource test_source;
  TestSource other_source;

  // Check the equality operators defined for NotificationSource
  EXPECT_TRUE(Source<TestSource>(&test_source) ==
              Source<TestSource>(&test_source));
  EXPECT_TRUE(Source<TestSource>(&test_source) !=
              Source<TestSource>(&other_source));

  TestObserver all_types_all_sources;
  TestObserver idle_all_sources;
  TestObserver all_types_test_source;
  TestObserver idle_test_source;

  // Make sure it doesn't freak out when there are no observers.
  NotificationService* service = NotificationService::current();
  service->Notify(kNotification1,
                  Source<TestSource>(&test_source),
                  NotificationService::NoDetails());

  registrar_.Add(&all_types_all_sources, NOTIFICATION_ALL,
                 NotificationService::AllSources());
  registrar_.Add(&idle_all_sources, kNotification1,
                 NotificationService::AllSources());
  registrar_.Add(&all_types_test_source, NOTIFICATION_ALL,
                 Source<TestSource>(&test_source));
  registrar_.Add(&idle_test_source, kNotification1,
                 Source<TestSource>(&test_source));

  EXPECT_EQ(0, all_types_all_sources.notification_count());
  EXPECT_EQ(0, idle_all_sources.notification_count());
  EXPECT_EQ(0, all_types_test_source.notification_count());
  EXPECT_EQ(0, idle_test_source.notification_count());

  service->Notify(kNotification1,
                  Source<TestSource>(&test_source),
                  NotificationService::NoDetails());

  EXPECT_EQ(1, all_types_all_sources.notification_count());
  EXPECT_EQ(1, idle_all_sources.notification_count());
  EXPECT_EQ(1, all_types_test_source.notification_count());
  EXPECT_EQ(1, idle_test_source.notification_count());

  service->Notify(kNotification2,
                  Source<TestSource>(&test_source),
                  NotificationService::NoDetails());

  EXPECT_EQ(2, all_types_all_sources.notification_count());
  EXPECT_EQ(1, idle_all_sources.notification_count());
  EXPECT_EQ(2, all_types_test_source.notification_count());
  EXPECT_EQ(1, idle_test_source.notification_count());

  service->Notify(kNotification1,
                  Source<TestSource>(&other_source),
                  NotificationService::NoDetails());

  EXPECT_EQ(3, all_types_all_sources.notification_count());
  EXPECT_EQ(2, idle_all_sources.notification_count());
  EXPECT_EQ(2, all_types_test_source.notification_count());
  EXPECT_EQ(1, idle_test_source.notification_count());

  service->Notify(kNotification2,
                  Source<TestSource>(&other_source),
                  NotificationService::NoDetails());

  EXPECT_EQ(4, all_types_all_sources.notification_count());
  EXPECT_EQ(2, idle_all_sources.notification_count());
  EXPECT_EQ(2, all_types_test_source.notification_count());
  EXPECT_EQ(1, idle_test_source.notification_count());

  // Try send with NULL source.
  service->Notify(kNotification1,
                  NotificationService::AllSources(),
                  NotificationService::NoDetails());

  EXPECT_EQ(5, all_types_all_sources.notification_count());
  EXPECT_EQ(3, idle_all_sources.notification_count());
  EXPECT_EQ(2, all_types_test_source.notification_count());
  EXPECT_EQ(1, idle_test_source.notification_count());

  registrar_.RemoveAll();

  service->Notify(kNotification1,
                  Source<TestSource>(&test_source),
                  NotificationService::NoDetails());

  EXPECT_EQ(5, all_types_all_sources.notification_count());
  EXPECT_EQ(3, idle_all_sources.notification_count());
  EXPECT_EQ(2, all_types_test_source.notification_count());
  EXPECT_EQ(1, idle_test_source.notification_count());
}

TEST_F(NotificationServiceImplTest, MultipleRegistration) {
  TestSource test_source;

  TestObserver idle_test_source;

  NotificationService* service = NotificationService::current();

  registrar_.Add(&idle_test_source, kNotification1,
                 Source<TestSource>(&test_source));
  registrar_.Add(&idle_test_source, NOTIFICATION_ALL,
                 Source<TestSource>(&test_source));

  service->Notify(kNotification1,
                  Source<TestSource>(&test_source),
                  NotificationService::NoDetails());
  EXPECT_EQ(2, idle_test_source.notification_count());

  registrar_.Remove(&idle_test_source, kNotification1,
                    Source<TestSource>(&test_source));

  service->Notify(kNotification1,
                 Source<TestSource>(&test_source),
                 NotificationService::NoDetails());
  EXPECT_EQ(3, idle_test_source.notification_count());

  registrar_.Remove(&idle_test_source, NOTIFICATION_ALL,
                    Source<TestSource>(&test_source));

  service->Notify(kNotification1,
                  Source<TestSource>(&test_source),
                  NotificationService::NoDetails());
  EXPECT_EQ(3, idle_test_source.notification_count());
}

}  // namespace content
