// Copyright 2018 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/notifications/notification_storage.h"

#include "base/bind.h"
#include "base/guid.h"
#include "base/run_loop.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"

namespace content {

class NotificationStorageTest : public ::testing::Test {
 public:
  NotificationStorageTest()
      : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
        origin_(GURL("https://example.com")),
        success_(false),
        service_worker_registration_id_(
            blink::mojom::kInvalidServiceWorkerRegistrationId) {
    helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath());
    storage_ =
        std::make_unique<NotificationStorage>(helper_->context_wrapper());
  }

  void DidRegisterServiceWorker(base::OnceClosure quit_closure,
                                blink::ServiceWorkerStatusCode status,
                                const std::string& status_message,
                                int64_t service_worker_registration_id) {
    DCHECK(service_worker_registration_id_);
    EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status) << status_message;

    service_worker_registration_id_ = service_worker_registration_id;

    std::move(quit_closure).Run();
  }

  void DidFindServiceWorkerRegistration(
      scoped_refptr<ServiceWorkerRegistration>* out_service_worker_registration,
      base::OnceClosure quit_closure,
      blink::ServiceWorkerStatusCode status,
      scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
    DCHECK(out_service_worker_registration);
    EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
        << blink::ServiceWorkerStatusToString(status);

    *out_service_worker_registration = service_worker_registration;

    std::move(quit_closure).Run();
  }

  // Registers a Service Worker for the testing origin and returns its
  // |service_worker_registration_id|. If registration failed, this will be
  // blink::mojom::kInvalidServiceWorkerRegistrationId. The
  // ServiceWorkerRegistration will be kept alive for the test's lifetime.
  int64_t RegisterServiceWorker() {
    GURL script_url = origin_;

    {
      blink::mojom::ServiceWorkerRegistrationOptions options;
      options.scope = origin_;
      base::RunLoop run_loop;
      helper_->context()->RegisterServiceWorker(
          script_url, options,
          base::BindOnce(&NotificationStorageTest::DidRegisterServiceWorker,
                         base::Unretained(this), run_loop.QuitClosure()));
      run_loop.Run();
    }

    if (service_worker_registration_id_ ==
        blink::mojom::kInvalidServiceWorkerRegistrationId) {
      ADD_FAILURE() << "Could not obtain a valid Service Worker registration";
      return blink::mojom::kInvalidServiceWorkerRegistrationId;
    }

    scoped_refptr<ServiceWorkerRegistration> service_worker_registration;

    {
      base::RunLoop run_loop;
      helper_->context()->storage()->FindRegistrationForId(
          service_worker_registration_id_, origin_,
          base::BindOnce(
              &NotificationStorageTest::DidFindServiceWorkerRegistration,
              base::Unretained(this), &service_worker_registration,
              run_loop.QuitClosure()));
      run_loop.Run();
    }

    // Wait for the worker to be activated.
    thread_bundle_.RunUntilIdle();

    if (!service_worker_registration) {
      ADD_FAILURE() << "Could not find the new Service Worker registration.";
      return blink::mojom::kInvalidServiceWorkerRegistrationId;
    }

    service_worker_registrations_.push_back(
        std::move(service_worker_registration));

    return service_worker_registration_id_;
  }

  void DidWriteNotificationDataSynchronous(base::OnceClosure quit_closure,
                                           bool success,
                                           const std::string& notification_id) {
    success_ = success;
    notification_id_ = notification_id;
    std::move(quit_closure).Run();
  }

  void WriteNotificationDataSynchronous(const NotificationDatabaseData& data) {
    base::RunLoop run_loop;
    storage_->WriteNotificationData(
        data, base::Bind(
                  &NotificationStorageTest::DidWriteNotificationDataSynchronous,
                  base::Unretained(this), run_loop.QuitClosure()));
    run_loop.Run();
  }

  void DidReadNotificationDataAndRecordInteractionSynchronous(
      base::OnceClosure quit_closure,
      bool success,
      const NotificationDatabaseData& data) {
    success_ = success;
    out_data_ = data;
    std::move(quit_closure).Run();
  }

  NotificationDatabaseData ReadNotificationDataAndRecordInteractionSynchronous(
      int64_t service_worker_registration_id,
      const std::string& notification_id,
      PlatformNotificationContext::Interaction interaction) {
    base::RunLoop run_loop;
    storage_->ReadNotificationDataAndRecordInteraction(
        service_worker_registration_id, notification_id, interaction,
        base::Bind(&NotificationStorageTest::
                       DidReadNotificationDataAndRecordInteractionSynchronous,
                   base::Unretained(this), run_loop.QuitClosure()));
    run_loop.Run();
    return out_data_;
  }

  // Generates a random notification ID. The format of the ID is opaque.
  std::string GenerateNotificationId() { return base::GenerateGUID(); }

 protected:
  TestBrowserThreadBundle thread_bundle_;  // Must be first member
  std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
  GURL origin_;
  TestBrowserContext browser_context_;
  bool success_;
  int64_t service_worker_registration_id_;
  NotificationDatabaseData out_data_;

 private:
  std::unique_ptr<NotificationStorage> storage_;
  std::string notification_id_;

  // Vector of ServiceWorkerRegistration instances that have to be kept alive
  // for the lifetime of this test.
  std::vector<scoped_refptr<ServiceWorkerRegistration>>
      service_worker_registrations_;
};

TEST_F(NotificationStorageTest, WriteReadNotification) {
  NotificationDatabaseData data;
  data.notification_id = GenerateNotificationId();
  data.origin = origin_;
  data.service_worker_registration_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
            data.service_worker_registration_id);
  WriteNotificationDataSynchronous(data);
  ASSERT_TRUE(success_);

  NotificationDatabaseData read_data =
      ReadNotificationDataAndRecordInteractionSynchronous(
          data.service_worker_registration_id, data.notification_id,
          PlatformNotificationContext::Interaction::NONE);
  ASSERT_TRUE(success_);
  EXPECT_EQ(data.origin, read_data.origin);
  EXPECT_EQ(data.notification_id, read_data.notification_id);
  EXPECT_EQ(data.service_worker_registration_id,
            read_data.service_worker_registration_id);
}

TEST_F(NotificationStorageTest, ReadInvalidNotification) {
  int64_t service_worker_registration_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
            service_worker_registration_id);
  ReadNotificationDataAndRecordInteractionSynchronous(
      service_worker_registration_id, "bad_id",
      PlatformNotificationContext::Interaction::NONE);
  ASSERT_FALSE(success_);
}

TEST_F(NotificationStorageTest, ReadAndUpdateInteraction) {
  NotificationDatabaseData data, read_data;
  data.notification_id = GenerateNotificationId();
  data.origin = origin_;
  data.service_worker_registration_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
            data.service_worker_registration_id);

  WriteNotificationDataSynchronous(data);
  ASSERT_TRUE(success_);

  // Check that the time deltas have not yet been set.
  EXPECT_FALSE(read_data.time_until_first_click_millis.has_value());
  EXPECT_FALSE(read_data.time_until_last_click_millis.has_value());
  EXPECT_FALSE(read_data.time_until_close_millis.has_value());

  // Check that when a notification has an interaction, the appropriate field is
  // updated on the read.
  read_data = ReadNotificationDataAndRecordInteractionSynchronous(
      data.service_worker_registration_id, data.notification_id,
      PlatformNotificationContext::Interaction::CLICKED);
  ASSERT_TRUE(success_);
  EXPECT_EQ(1, read_data.num_clicks);

  read_data = ReadNotificationDataAndRecordInteractionSynchronous(
      data.service_worker_registration_id, data.notification_id,
      PlatformNotificationContext::Interaction::ACTION_BUTTON_CLICKED);
  ASSERT_TRUE(success_);
  EXPECT_EQ(1, read_data.num_action_button_clicks);

  read_data = ReadNotificationDataAndRecordInteractionSynchronous(
      data.service_worker_registration_id, data.notification_id,
      PlatformNotificationContext::Interaction::ACTION_BUTTON_CLICKED);
  ASSERT_TRUE(success_);
  EXPECT_EQ(2, read_data.num_action_button_clicks);

  // Check that the click timestamps are correctly updated.
  EXPECT_TRUE(read_data.time_until_first_click_millis.has_value());
  EXPECT_TRUE(read_data.time_until_last_click_millis.has_value());

  // Check that when a read with a CLOSED interaction occurs, the correct
  // field is updated.
  read_data = ReadNotificationDataAndRecordInteractionSynchronous(
      data.service_worker_registration_id, data.notification_id,
      PlatformNotificationContext::Interaction::CLOSED);
  ASSERT_TRUE(success_);
  EXPECT_EQ(true, read_data.time_until_close_millis.has_value());
}

}  // namespace content
