// 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 "content/browser/service_worker/service_worker_dispatcher_host.h"

#include <stdint.h>

#include <utility>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/run_loop.h"
#include "base/time/time.h"
#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
#include "content/browser/service_worker/embedded_worker_status.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
#include "content/browser/service_worker/service_worker_object_host.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/child_process_termination_info.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/edk/embedder/embedder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"

namespace content {
namespace service_worker_dispatcher_host_unittest {

static void SaveStatusCallback(bool* called,
                               blink::ServiceWorkerStatusCode* out,
                               blink::ServiceWorkerStatusCode status) {
  *called = true;
  *out = status;
}

struct RemoteProviderInfo {
  mojom::ServiceWorkerContainerHostAssociatedPtr host_ptr;
  mojom::ServiceWorkerContainerAssociatedRequest client_request;
};

std::unique_ptr<ServiceWorkerNavigationHandleCore> CreateNavigationHandleCore(
    ServiceWorkerContextWrapper* context_wrapper) {
  std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core;
  BrowserThread::PostTaskAndReplyWithResult(
      BrowserThread::UI, FROM_HERE,
      base::Bind(
          [](ServiceWorkerContextWrapper* wrapper) {
            return std::make_unique<ServiceWorkerNavigationHandleCore>(nullptr,
                                                                       wrapper);
          },
          base::RetainedRef(context_wrapper)),
      base::Bind(
          [](std::unique_ptr<ServiceWorkerNavigationHandleCore>* dest,
             std::unique_ptr<ServiceWorkerNavigationHandleCore> src) {
            *dest = std::move(src);
          },
          &navigation_handle_core));
  base::RunLoop().RunUntilIdle();
  return navigation_handle_core;
}

class ServiceWorkerDispatcherHostTest : public testing::Test {
 protected:
  ServiceWorkerDispatcherHostTest()
      : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}

  void SetUp() override {
    Initialize(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
    mojo::edk::SetDefaultProcessErrorCallback(base::BindRepeating(
        &ServiceWorkerDispatcherHostTest::OnMojoError, base::Unretained(this)));
  }

  void TearDown() override {
    version_ = nullptr;
    registration_ = nullptr;
    helper_.reset();
    mojo::edk::SetDefaultProcessErrorCallback(
        mojo::edk::ProcessErrorCallback());
  }

  void OnMojoError(const std::string& error) { bad_messages_.push_back(error); }

  ServiceWorkerContextCore* context() { return helper_->context(); }
  ServiceWorkerContextWrapper* context_wrapper() {
    return helper_->context_wrapper();
  }

  void Initialize(std::unique_ptr<EmbeddedWorkerTestHelper> helper) {
    helper_.reset(helper.release());
    // Replace the default dispatcher host.
    int process_id = helper_->mock_render_process_id();
    dispatcher_host_.reset(
        new ServiceWorkerDispatcherHost(context_wrapper(), process_id));
  }

  void SetUpRegistration(const GURL& scope, const GURL& script_url) {
    blink::mojom::ServiceWorkerRegistrationOptions options;
    options.scope = scope;
    registration_ =
        new ServiceWorkerRegistration(options, 1L, context()->AsWeakPtr());
    version_ = new ServiceWorkerVersion(registration_.get(), script_url, 1L,
                                        context()->AsWeakPtr());
    std::vector<ServiceWorkerDatabase::ResourceRecord> records;
    records.push_back(
        ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100));
    version_->script_cache_map()->SetResources(records);
    version_->SetMainScriptHttpResponseInfo(
        EmbeddedWorkerTestHelper::CreateHttpResponseInfo());
    version_->set_fetch_handler_existence(
        ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
    version_->SetStatus(ServiceWorkerVersion::INSTALLING);

    // Make the registration findable via storage functions.
    context()->storage()->LazyInitializeForTest(base::DoNothing());
    base::RunLoop().RunUntilIdle();
    bool called = false;
    blink::ServiceWorkerStatusCode status =
        blink::SERVICE_WORKER_ERROR_MAX_VALUE;
    context()->storage()->StoreRegistration(
        registration_.get(), version_.get(),
        base::BindOnce(&SaveStatusCallback, &called, &status));
    base::RunLoop().RunUntilIdle();
    EXPECT_TRUE(called);
    EXPECT_EQ(blink::SERVICE_WORKER_OK, status);
  }

  RemoteProviderInfo SendProviderCreated(
      ServiceWorkerProviderHostInfo host_info) {
    DCHECK(!host_info.host_request.is_pending());
    DCHECK(!host_info.client_ptr_info.is_valid());

    RemoteProviderInfo remote_info;
    mojom::ServiceWorkerContainerAssociatedPtrInfo client;
    remote_info.client_request = mojo::MakeRequest(&client);
    host_info.host_request = mojo::MakeRequest(&remote_info.host_ptr);
    host_info.client_ptr_info = std::move(client);

    mojom::ServiceWorkerDispatcherHostAssociatedPtr ptr;
    dispatcher_host_->AddBinding(
        mojo::MakeRequestAssociatedWithDedicatedPipe(&ptr));
    ptr->OnProviderCreated(std::move(host_info));
    base::RunLoop().RunUntilIdle();
    return remote_info;
  }

  TestBrowserThreadBundle browser_thread_bundle_;
  std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
  std::unique_ptr<ServiceWorkerDispatcherHost, BrowserThread::DeleteOnIOThread>
      dispatcher_host_;
  scoped_refptr<ServiceWorkerRegistration> registration_;
  scoped_refptr<ServiceWorkerVersion> version_;
  std::vector<std::string> bad_messages_;
};

TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) {
  int process_id = helper_->mock_render_process_id();
  std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core;

  {
    // Prepare the first navigation handle to create provider host.
    const int kProviderId = -2;
    navigation_handle_core =
        CreateNavigationHandleCore(helper_->context_wrapper());
    ASSERT_TRUE(navigation_handle_core);
    base::WeakPtr<ServiceWorkerProviderHost> host =
        ServiceWorkerProviderHost::PreCreateNavigationHost(
            context()->AsWeakPtr(), true /* are_ancestors_secure */,
            base::RepeatingCallback<WebContents*(void)>());
    EXPECT_EQ(kProviderId, host->provider_id());
    ServiceWorkerProviderHostInfo host_info(kProviderId, 1 /* route_id */,
                                            host->provider_type(),
                                            host->is_parent_frame_secure());
    navigation_handle_core->DidPreCreateProviderHost(kProviderId);
    RemoteProviderInfo remote_provider =
        SendProviderCreated(std::move(host_info));
    EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId));

    // Releasing the interface pointer destroys the counterpart.
    remote_provider.host_ptr.reset();
    base::RunLoop().RunUntilIdle();
    EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId));
  }

  {
    // Two with the same ID should be seen as a bad message.
    const int kProviderId = 99;
    RemoteProviderInfo remote_provider_1 =
        SendProviderCreated(ServiceWorkerProviderHostInfo(
            kProviderId, 1 /* route_id */,
            blink::mojom::ServiceWorkerProviderType::kForWindow,
            true /* is_parent_frame_secure */));
    EXPECT_TRUE(bad_messages_.empty());
    RemoteProviderInfo remote_provider_2 =
        SendProviderCreated(ServiceWorkerProviderHostInfo(
            kProviderId, 1 /* route_id */,
            blink::mojom::ServiceWorkerProviderType::kForWindow,
            true /* is_parent_frame_secure */));
    ASSERT_EQ(1u, bad_messages_.size());
    EXPECT_EQ("SWDH_PROVIDER_CREATED_DUPLICATE_ID", bad_messages_[0]);
  }

  {
    // Prepare another navigation handle to create another provider host.
    const int kProviderId = -3;
    navigation_handle_core =
        CreateNavigationHandleCore(helper_->context_wrapper());
    base::WeakPtr<ServiceWorkerProviderHost> host =
        ServiceWorkerProviderHost::PreCreateNavigationHost(
            context()->AsWeakPtr(), true /* are_ancestors_secure */,
            base::RepeatingCallback<WebContents*(void)>());
    EXPECT_EQ(kProviderId, host->provider_id());
    ServiceWorkerProviderHostInfo host_info(kProviderId, 2 /* route_id */,
                                            host->provider_type(),
                                            host->is_parent_frame_secure());
    navigation_handle_core->DidPreCreateProviderHost(kProviderId);
    RemoteProviderInfo remote_provider =
        SendProviderCreated(std::move(host_info));
    EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId));

    // Simulate that the corresponding renderer process died.
    dispatcher_host_->RenderProcessExited(nullptr /* host */,
                                          ChildProcessTerminationInfo());
    base::RunLoop().RunUntilIdle();
    EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId));
  }
}

TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
  GURL pattern = GURL("https://www.example.com/");
  GURL script_url = GURL("https://www.example.com/service_worker.js");
  int process_id = helper_->mock_render_process_id();

  const int64_t kProviderId = 99;
  ServiceWorkerProviderHostInfo host_info_1(
      kProviderId, MSG_ROUTING_NONE,
      blink::mojom::ServiceWorkerProviderType::kForWindow,
      true /* is_parent_frame_secure */);
  RemoteProviderInfo remote_provider_1 =
      SendProviderCreated(std::move(host_info_1));
  ServiceWorkerProviderHost* provider_host = context()->GetProviderHost(
      helper_->mock_render_process_id(), kProviderId);
  SetUpRegistration(pattern, script_url);
  EXPECT_EQ(kProviderId, provider_host->provider_id());

  // Start up the worker.
  bool called = false;
  blink::ServiceWorkerStatusCode status = blink::SERVICE_WORKER_ERROR_ABORT;
  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
                        base::BindOnce(&SaveStatusCallback, &called, &status));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(called);
  EXPECT_EQ(blink::SERVICE_WORKER_OK, status);
  EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId));
  EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());

  // Simulate that the corresponding renderer process died.
  dispatcher_host_->RenderProcessExited(nullptr /* host */,
                                        ChildProcessTerminationInfo());
  base::RunLoop().RunUntilIdle();
  // The dispatcher host should have removed the provider host.
  EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId));
  // The EmbeddedWorkerInstance should still think it is running, since it will
  // clean itself up when its Mojo connection to the renderer breaks.
  EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());

  // Simulate that the browser process reused the dispatcher host due to reuse
  // of the RenderProcessHost for another new renderer process, then the new
  // renderer process creates a provider with the same |kProviderId|. Since the
  // dispatcher host already cleaned up the old provider host, the new one won't
  // complain.
  ServiceWorkerProviderHostInfo host_info_2(
      kProviderId, MSG_ROUTING_NONE,
      blink::mojom::ServiceWorkerProviderType::kForWindow,
      true /* is_parent_frame_secure */);
  RemoteProviderInfo remote_provider_2 =
      SendProviderCreated(std::move(host_info_2));
  EXPECT_TRUE(bad_messages_.empty());
}

}  // namespace service_worker_dispatcher_host_unittest
}  // namespace content
