// 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 {

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);
  }

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

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

  virtual void BadMessageReceived() override {
    ++bad_messages_received_count_;
  }

  int bad_messages_received_count_;

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

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

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

  virtual void TearDown() {
    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() {}
  virtual 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_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());

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

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
  SendRegister(kProviderId,
               GURL("https://www.example.com/"),
               GURL("https://foo.example.com/bar"));
  EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);

  // Scope has a different host
  SendRegister(kProviderId,
               GURL("https://foo.example.com/"),
               GURL("https://www.example.com/bar"));
  EXPECT_EQ(2, dispatcher_host_->bad_messages_received_count_);

  // Script has a different port
  SendRegister(kProviderId,
               GURL("https://www.example.com/"),
               GURL("https://www.example.com:8080/bar"));
  EXPECT_EQ(3, dispatcher_host_->bad_messages_received_count_);

  // Scope has a different transport
  SendRegister(kProviderId,
               GURL("wss://www.example.com/"),
               GURL("https://www.example.com/bar"));
  EXPECT_EQ(4, dispatcher_host_->bad_messages_received_count_);

  // Script and scope have a different host but match each other
  SendRegister(kProviderId,
               GURL("https://foo.example.com/"),
               GURL("https://foo.example.com/bar"));
  EXPECT_EQ(5, dispatcher_host_->bad_messages_received_count_);

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

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());

  SendUnregister(kProviderId, GURL("https://foo.example.com/"));
  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());

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

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());

  SendGetRegistration(kProviderId, GURL("https://foo.example.com/"));
  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());

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

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

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

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

}  // namespace content
