// 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 "base/command_line.h"
#include "base/files/file_path.h"
#include "base/run_loop.h"
#include "content/browser/browser_thread_impl.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_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/common/service_worker/embedded_worker_messages.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/mock_resource_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/test_content_browser_client.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

namespace {

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

}

static const int kRenderProcessId = 1;

class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost {
 public:
  TestingServiceWorkerDispatcherHost(
      int process_id,
      ServiceWorkerContextWrapper* context_wrapper,
      ResourceContext* resource_context,
      EmbeddedWorkerTestHelper* helper)
      : ServiceWorkerDispatcherHost(process_id, NULL, resource_context),
        bad_messages_received_count_(0),
        helper_(helper) {
    Init(context_wrapper);
  }

  bool Send(IPC::Message* message) override { return helper_->Send(message); }

  IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); }

  void BadMessageReceived() override { ++bad_messages_received_count_; }

  int bad_messages_received_count_;

 protected:
  EmbeddedWorkerTestHelper* helper_;
  ~TestingServiceWorkerDispatcherHost() override {}
};

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

  void SetUp() override {
    helper_.reset(new EmbeddedWorkerTestHelper(kRenderProcessId));
    dispatcher_host_ = new TestingServiceWorkerDispatcherHost(
        kRenderProcessId, context_wrapper(), &resource_context_, helper_.get());
  }

  void TearDown() override { helper_.reset(); }

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

  void SendRegister(int64 provider_id, GURL pattern, GURL worker_url) {
    dispatcher_host_->OnMessageReceived(
        ServiceWorkerHostMsg_RegisterServiceWorker(
            -1, -1, provider_id, pattern, worker_url));
    base::RunLoop().RunUntilIdle();
  }

  void Register(int64 provider_id,
                GURL pattern,
                GURL worker_url,
                uint32 expected_message) {
    SendRegister(provider_id, pattern, worker_url);
    EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching(
        expected_message));
    dispatcher_host_->ipc_sink()->ClearMessages();
  }

  void SendUnregister(int64 provider_id, GURL pattern) {
    dispatcher_host_->OnMessageReceived(
        ServiceWorkerHostMsg_UnregisterServiceWorker(
            -1, -1, provider_id, pattern));
    base::RunLoop().RunUntilIdle();
  }

  void Unregister(int64 provider_id, GURL pattern, uint32 expected_message) {
    SendUnregister(provider_id, pattern);
    EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching(
        expected_message));
    dispatcher_host_->ipc_sink()->ClearMessages();
  }

  void SendGetRegistration(int64 provider_id, GURL document_url) {
    dispatcher_host_->OnMessageReceived(
        ServiceWorkerHostMsg_GetRegistration(
            -1, -1, provider_id, document_url));
    base::RunLoop().RunUntilIdle();
  }

  void GetRegistration(int64 provider_id,
                       GURL document_url,
                       uint32 expected_message) {
    SendGetRegistration(provider_id, document_url);
    EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching(
        expected_message));
    dispatcher_host_->ipc_sink()->ClearMessages();
  }

  TestBrowserThreadBundle browser_thread_bundle_;
  content::MockResourceContext resource_context_;
  scoped_ptr<EmbeddedWorkerTestHelper> helper_;
  scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host_;
};

class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient {
 public:
  ServiceWorkerTestContentBrowserClient() {}
  bool AllowServiceWorker(const GURL& scope,
                          const GURL& first_party,
                          content::ResourceContext* context) override {
    return false;
  }
};

TEST_F(ServiceWorkerDispatcherHostTest,
       Register_ContentSettingsDisallowsServiceWorker) {
  ServiceWorkerTestContentBrowserClient test_browser_client;
  ContentBrowserClient* old_browser_client =
      SetBrowserClientForTesting(&test_browser_client);

  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  Register(kProviderId,
           GURL("https://www.example.com/"),
           GURL("https://www.example.com/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);
  Unregister(kProviderId,
             GURL("https://www.example.com/"),
             ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID);
  GetRegistration(kProviderId,
                  GURL("https://www.example.com/"),
                  ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID);

  SetBrowserClientForTesting(old_browser_client);
}

TEST_F(ServiceWorkerDispatcherHostTest, Register_HTTPS) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  Register(kProviderId,
           GURL("https://www.example.com/"),
           GURL("https://www.example.com/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistered::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, Register_NonSecureTransportLocalhost) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("http://127.0.0.3:81/foo"));
  context()->AddProviderHost(host.Pass());

  Register(kProviderId,
           GURL("http://127.0.0.3:81/bar"),
           GURL("http://127.0.0.3:81/baz"),
           ServiceWorkerMsg_ServiceWorkerRegistered::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, Register_InvalidScopeShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  SendRegister(
      kProviderId, GURL(""), GURL("https://www.example.com/bar/hoge.js"));
  EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
}

TEST_F(ServiceWorkerDispatcherHostTest, Register_InvalidScriptShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  SendRegister(kProviderId, GURL("https://www.example.com/bar/"), GURL(""));
  EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
}

TEST_F(ServiceWorkerDispatcherHostTest, Register_NonSecureOriginShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("http://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  Register(kProviderId,
           GURL("http://www.example.com/"),
           GURL("http://www.example.com/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, Register_CrossOriginShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  // Script has a different host
  Register(kProviderId,
           GURL("https://www.example.com/"),
           GURL("https://foo.example.com/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);

  // Scope has a different host
  Register(kProviderId,
           GURL("https://foo.example.com/"),
           GURL("https://www.example.com/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);

  // Script has a different port
  Register(kProviderId,
           GURL("https://www.example.com/"),
           GURL("https://www.example.com:8080/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);

  // Scope has a different transport
  Register(kProviderId,
           GURL("wss://www.example.com/"),
           GURL("https://www.example.com/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);

  // Script and scope have a different host but match each other
  Register(kProviderId,
           GURL("https://foo.example.com/"),
           GURL("https://foo.example.com/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);

  // Script and scope URLs are invalid
  SendRegister(kProviderId,
               GURL(),
               GURL("h@ttps://@"));
  EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
}

TEST_F(ServiceWorkerDispatcherHostTest,
       Register_FileSystemDocumentShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("filesystem:https://www.example.com/temporary/a"));
  context()->AddProviderHost(host.Pass());

  Register(kProviderId,
           GURL("filesystem:https://www.example.com/temporary/"),
           GURL("https://www.example.com/temporary/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);

  Register(kProviderId,
           GURL("https://www.example.com/temporary/"),
           GURL("filesystem:https://www.example.com/temporary/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);

  Register(kProviderId,
           GURL("filesystem:https://www.example.com/temporary/"),
           GURL("filesystem:https://www.example.com/temporary/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest,
       Register_FileSystemScriptOrScopeShouldFail) {

  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/temporary/"));
  context()->AddProviderHost(host.Pass());

  Register(kProviderId,
           GURL("filesystem:https://www.example.com/temporary/"),
           GURL("https://www.example.com/temporary/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);

  Register(kProviderId,
           GURL("https://www.example.com/temporary/"),
           GURL("filesystem:https://www.example.com/temporary/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);

  Register(kProviderId,
           GURL("filesystem:https://www.example.com/temporary/"),
           GURL("filesystem:https://www.example.com/temporary/bar"),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, Unregister_HTTPS) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  Unregister(kProviderId,
             GURL("https://www.example.com/"),
             ServiceWorkerMsg_ServiceWorkerUnregistered::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest,
       Unregister_NonSecureTransportLocalhost) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("http://localhost/foo"));
  context()->AddProviderHost(host.Pass());

  Unregister(kProviderId,
             GURL("http://localhost/"),
             ServiceWorkerMsg_ServiceWorkerUnregistered::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, Unregister_CrossOriginShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  Unregister(kProviderId,
             GURL("https://foo.example.com/"),
             ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, Unregister_InvalidScopeShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  SendUnregister(kProviderId, GURL(""));
  EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
}

TEST_F(ServiceWorkerDispatcherHostTest, Unregister_NonSecureOriginShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("http://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  Unregister(kProviderId,
             GURL("http://www.example.com/"),
             ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, EarlyContextDeletion) {
  helper_->ShutdownContext();

  // Let the shutdown reach the simulated IO thread.
  base::RunLoop().RunUntilIdle();

  Register(-1,
           GURL(),
           GURL(),
           ServiceWorkerMsg_ServiceWorkerRegistrationError::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) {
  const int kProviderId = 1001;  // Test with a value != kRenderProcessId.

  dispatcher_host_->OnMessageReceived(
      ServiceWorkerHostMsg_ProviderCreated(kProviderId));
  EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId));

  // Two with the same ID should be seen as a bad message.
  dispatcher_host_->OnMessageReceived(
      ServiceWorkerHostMsg_ProviderCreated(kProviderId));
  EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);

  dispatcher_host_->OnMessageReceived(
      ServiceWorkerHostMsg_ProviderDestroyed(kProviderId));
  EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId));

  // Destroying an ID that does not exist warrants a bad message.
  dispatcher_host_->OnMessageReceived(
      ServiceWorkerHostMsg_ProviderDestroyed(kProviderId));
  EXPECT_EQ(2, dispatcher_host_->bad_messages_received_count_);

  // Deletion of the dispatcher_host should cause providers for that
  // process to get deleted as well.
  dispatcher_host_->OnMessageReceived(
      ServiceWorkerHostMsg_ProviderCreated(kProviderId));
  EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId));
  EXPECT_TRUE(dispatcher_host_->HasOneRef());
  dispatcher_host_ = NULL;
  EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId));
}

TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_SameOrigin) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  GetRegistration(kProviderId,
                  GURL("https://www.example.com/"),
                  ServiceWorkerMsg_DidGetRegistration::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_CrossOriginShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  GetRegistration(kProviderId,
                  GURL("https://foo.example.com/"),
                  ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest,
       GetRegistration_InvalidScopeShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("https://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  SendGetRegistration(kProviderId, GURL(""));
  EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
}

TEST_F(ServiceWorkerDispatcherHostTest,
       GetRegistration_NotSecureOriginShouldFail) {
  const int64 kProviderId = 99;  // Dummy value
  scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
      kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL));
  host->SetDocumentUrl(GURL("http://www.example.com/foo"));
  context()->AddProviderHost(host.Pass());

  GetRegistration(kProviderId,
                  GURL("http://www.example.com/"),
                  ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_EarlyContextDeletion) {
  helper_->ShutdownContext();

  // Let the shutdown reach the simulated IO thread.
  base::RunLoop().RunUntilIdle();

  GetRegistration(-1,
                  GURL(),
                  ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID);
}

TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
  // Add a provider and worker.
  const int64 kProviderId = 99;  // Dummy value
  dispatcher_host_->OnMessageReceived(
      ServiceWorkerHostMsg_ProviderCreated(kProviderId));

  GURL pattern = GURL("http://www.example.com/");
  scoped_refptr<ServiceWorkerRegistration> registration(
      new ServiceWorkerRegistration(pattern,
                                    1L,
                                    helper_->context()->AsWeakPtr()));
  scoped_refptr<ServiceWorkerVersion> version(
      new ServiceWorkerVersion(registration.get(),
                               GURL("http://www.example.com/service_worker.js"),
                               1L,
                               helper_->context()->AsWeakPtr()));
  helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);

  // Start up the worker.
  bool called;
  ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_ABORT;
  version->StartWorker(base::Bind(&SaveStatusCallback, &called, &status));
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(called);
  EXPECT_EQ(SERVICE_WORKER_OK, status);

  EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId));
  EXPECT_EQ(ServiceWorkerVersion::RUNNING, version->running_status());

  // Simulate the render process crashing.
  dispatcher_host_->OnFilterRemoved();

  // The dispatcher host should clean up the state from the process.
  EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId));
  EXPECT_EQ(ServiceWorkerVersion::STOPPED, version->running_status());

  // We should be able to hook up a new dispatcher host although the old object
  // is not yet destroyed. This is what the browser does when reusing a crashed
  // render process.
  scoped_refptr<TestingServiceWorkerDispatcherHost> new_dispatcher_host(
      new TestingServiceWorkerDispatcherHost(kRenderProcessId,
                                             context_wrapper(),
                                             &resource_context_,
                                             helper_.get()));

  // To show the new dispatcher can operate, simulate provider creation. Since
  // the old dispatcher cleaned up the old provider host, the new one won't
  // complain.
  new_dispatcher_host->OnMessageReceived(
      ServiceWorkerHostMsg_ProviderCreated(kProviderId));
  EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_);
}

}  // namespace content
