// Copyright 2014 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.

#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_TEST_UTILS_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_TEST_UTILS_H_

#include <memory>

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/memory/weak_ptr.h"
#include "base/task/post_task.h"
#include "content/browser/service_worker/service_worker_database.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/common/navigation_client.mojom.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"

namespace net {

class HttpResponseInfo;

}  // namespace net

namespace content {

class ServiceWorkerContextCore;
class ServiceWorkerProviderHost;
class ServiceWorkerStorage;
class ServiceWorkerVersion;

template <typename Arg>
void ReceiveResult(BrowserThread::ID run_quit_thread,
                   base::OnceClosure quit,
                   base::Optional<Arg>* out,
                   Arg actual) {
  *out = actual;
  if (!quit.is_null())
    base::PostTaskWithTraits(FROM_HERE, {run_quit_thread}, std::move(quit));
}

template <typename Arg>
base::OnceCallback<void(Arg)> CreateReceiver(BrowserThread::ID run_quit_thread,
                                             base::OnceClosure quit,
                                             base::Optional<Arg>* out) {
  return base::BindOnce(&ReceiveResult<Arg>, run_quit_thread, std::move(quit),
                        out);
}

base::OnceCallback<void(blink::ServiceWorkerStatusCode)>
ReceiveServiceWorkerStatus(base::Optional<blink::ServiceWorkerStatusCode>* out,
                           base::OnceClosure quit_closure);

// Container for keeping the Mojo connection to the service worker provider on
// the renderer alive.
class ServiceWorkerRemoteProviderEndpoint {
 public:
  ServiceWorkerRemoteProviderEndpoint();
  ServiceWorkerRemoteProviderEndpoint(
      ServiceWorkerRemoteProviderEndpoint&& other);
  ~ServiceWorkerRemoteProviderEndpoint();

  void BindForWindow(blink::mojom::ServiceWorkerProviderInfoForWindowPtr info);
  void BindForServiceWorker(
      blink::mojom::ServiceWorkerProviderInfoForStartWorkerPtr info);

  blink::mojom::ServiceWorkerContainerHostAssociatedPtr* host_ptr() {
    return &host_ptr_;
  }

  blink::mojom::ServiceWorkerContainerAssociatedRequest* client_request() {
    return &client_request_;
  }

 private:
  // Connects to a fake navigation client and keeps alive the message pipe on
  // which |host_ptr_info_| and |client_request_| are associated so that they
  // are usable. This is only for navigations. For service workers we can also
  // do the same thing by establishing a
  // blink::mojom::EmbeddedWorkerInstanceClient connection if in the future we
  // really need to make |host_ptr_info_| and |client_request_| usable for it.
  mojom::NavigationClientPtr navigation_client_;
  // Bound with content::ServiceWorkerProviderHost. The provider host will be
  // removed asynchronously when this pointer is closed.
  blink::mojom::ServiceWorkerContainerHostAssociatedPtr host_ptr_;
  // This is the other end of ServiceWorkerContainerAssociatedPtr owned by
  // content::ServiceWorkerProviderHost.
  blink::mojom::ServiceWorkerContainerAssociatedRequest client_request_;

  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRemoteProviderEndpoint);
};

base::WeakPtr<ServiceWorkerProviderHost> CreateProviderHostForWindow(
    int process_id,
    bool is_parent_frame_secure,
    base::WeakPtr<ServiceWorkerContextCore> context,
    ServiceWorkerRemoteProviderEndpoint* output_endpoint);

base::WeakPtr<ServiceWorkerProviderHost>
CreateProviderHostForServiceWorkerContext(
    int process_id,
    bool is_parent_frame_secure,
    ServiceWorkerVersion* hosted_version,
    base::WeakPtr<ServiceWorkerContextCore> context,
    ServiceWorkerRemoteProviderEndpoint* output_endpoint);

// Writes the script down to |storage| synchronously. This should not be used in
// base::RunLoop since base::RunLoop is used internally to wait for completing
// all of tasks. If it's in another base::RunLoop, consider to use
// WriteToDiskCacheAsync().
ServiceWorkerDatabase::ResourceRecord WriteToDiskCacheSync(
    ServiceWorkerStorage* storage,
    const GURL& script_url,
    int64_t resource_id,
    const std::vector<std::pair<std::string, std::string>>& headers,
    const std::string& body,
    const std::string& meta_data);

// Writes the script with custom net::HttpResponseInfo down to |storage|
// synchronously. This should not be used in base::RunLoop since base::RunLoop
// is used internally to wait for completing all of tasks. If it's in another
// base::RunLoop, consider to use WriteToDiskCacheWithCustomResponseInfoAsync().
ServiceWorkerDatabase::ResourceRecord
WriteToDiskCacheWithCustomResponseInfoSync(
    ServiceWorkerStorage* storage,
    const GURL& script_url,
    int64_t resource_id,
    std::unique_ptr<net::HttpResponseInfo> http_info,
    const std::string& body,
    const std::string& meta_data);

// Writes the script down to |storage| asynchronously. When completing tasks,
// |callback| will be called. You must wait for |callback| instead of
// base::RunUntilIdle because wiriting to the storage might happen on another
// thread and base::RunLoop could get idle before writes has not finished yet.
ServiceWorkerDatabase::ResourceRecord WriteToDiskCacheAsync(
    ServiceWorkerStorage* storage,
    const GURL& script_url,
    int64_t resource_id,
    const std::vector<std::pair<std::string, std::string>>& headers,
    const std::string& body,
    const std::string& meta_data,
    base::OnceClosure callback);

// Writes the script with custom net::HttpResponseInfo down to |storage|
// asynchronously. When completing tasks, |callback| will be called. You must
// wait for |callback| instead of base::RunUntilIdle because wiriting to the
// storage might happen on another thread and base::RunLoop could get idle
// before writes has not finished yet.
ServiceWorkerDatabase::ResourceRecord
WriteToDiskCacheWithCustomResponseInfoAsync(
    ServiceWorkerStorage* storage,
    const GURL& script_url,
    int64_t resource_id,
    std::unique_ptr<net::HttpResponseInfo> http_info,
    const std::string& body,
    const std::string& meta_data,
    base::OnceClosure callback);

// A test implementation of ServiceWorkerResponseReader.
//
// This class exposes the ability to expect reads (see ExpectRead*() below).
// Each call to ReadInfo() or ReadData() consumes another expected read, in the
// order those reads were expected, so:
//    reader->ExpectReadInfoOk(5, false);
//    reader->ExpectReadDataOk("abcdef", false);
//    reader->ExpectReadDataOk("ghijkl", false);
// Expects these calls, in this order:
//    reader->ReadInfo(...);  // reader writes 5 into
//                            // |info_buf->response_data_size|
//    reader->ReadData(...);  // reader writes "abcdef" into |buf|
//    reader->ReadData(...);  // reader writes "ghijkl" into |buf|
// If an unexpected call happens, this class DCHECKs.
// If an expected read is marked "async", it will not complete immediately, but
// must be completed by the test using CompletePendingRead().
// These is a convenience method AllExpectedReadsDone() which returns whether
// there are any expected reads that have not yet happened.
class MockServiceWorkerResponseReader : public ServiceWorkerResponseReader {
 public:
  MockServiceWorkerResponseReader();
  ~MockServiceWorkerResponseReader() override;

  // ServiceWorkerResponseReader overrides
  void ReadInfo(HttpResponseInfoIOBuffer* info_buf,
                OnceCompletionCallback callback) override;
  void ReadData(net::IOBuffer* buf,
                int buf_len,
                OnceCompletionCallback callback) override;

  // Test helpers. ExpectReadInfo() and ExpectReadData() give precise control
  // over both the data to be written and the result to return.
  // ExpectReadInfoOk() and ExpectReadDataOk() are convenience functions for
  // expecting successful reads, which always have their length as their result.

  // Expect a call to ReadInfo() on this reader. For these functions, |len| will
  // be used as |response_data_size|, not as the length of this particular read.
  void ExpectReadInfo(size_t len, bool async, int result);
  void ExpectReadInfoOk(size_t len, bool async);

  // Expect a call to ReadData() on this reader. For these functions, |len| is
  // the length of the data to be written back; in ExpectReadDataOk(), |len| is
  // implicitly the length of |data|.
  void ExpectReadData(const char* data, size_t len, bool async, int result);
  void ExpectReadDataOk(const std::string& data, bool async);

  // Convenient method for calling ExpectReadInfoOk() with the length being
  // |bytes_stored|, and ExpectReadDataOk() for each element of |stored_data|.
  void ExpectReadOk(const std::vector<std::string>& stored_data,
                    const size_t bytes_stored,
                    const bool async);

  // Complete a pending async read. It is an error to call this function without
  // a pending async read (ie, a previous call to ReadInfo() or ReadData()
  // having not run its callback yet).
  void CompletePendingRead();

  // Returns whether all expected reads have occurred.
  bool AllExpectedReadsDone() { return expected_reads_.size() == 0; }

 private:
  struct ExpectedRead {
    ExpectedRead(size_t len, bool async, int result)
        : data(nullptr), len(len), info(true), async(async), result(result) {}
    ExpectedRead(const char* data, size_t len, bool async, int result)
        : data(data), len(len), info(false), async(async), result(result) {}
    const char* data;
    size_t len;
    bool info;
    bool async;
    int result;
  };

  base::queue<ExpectedRead> expected_reads_;
  scoped_refptr<net::IOBuffer> pending_buffer_;
  size_t pending_buffer_len_;
  scoped_refptr<HttpResponseInfoIOBuffer> pending_info_;
  OnceCompletionCallback pending_callback_;

  DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseReader);
};

// A test implementation of ServiceWorkerResponseWriter.
//
// This class exposes the ability to expect writes (see ExpectWrite*Ok() below).
// Each write to this class via WriteInfo() or WriteData() consumes another
// expected write, in the order they were added, so:
//   writer->ExpectWriteInfoOk(5, false);
//   writer->ExpectWriteDataOk(6, false);
//   writer->ExpectWriteDataOk(6, false);
// Expects these calls, in this order:
//   writer->WriteInfo(...);  // checks that |buf->response_data_size| == 5
//   writer->WriteData(...);  // checks that 6 bytes are being written
//   writer->WriteData(...);  // checks that another 6 bytes are being written
// If this class receives an unexpected call to WriteInfo() or WriteData(), it
// DCHECKs.
// Expected writes marked async do not complete synchronously, but rather return
// without running their callback and need to be completed with
// CompletePendingWrite().
// A convenience method AllExpectedWritesDone() is exposed so tests can ensure
// that all expected writes have been consumed by matching calls to WriteInfo()
// or WriteData().
class MockServiceWorkerResponseWriter : public ServiceWorkerResponseWriter {
 public:
  MockServiceWorkerResponseWriter();
  ~MockServiceWorkerResponseWriter() override;

  // ServiceWorkerResponseWriter overrides
  void WriteInfo(HttpResponseInfoIOBuffer* info_buf,
                 OnceCompletionCallback callback) override;
  void WriteData(net::IOBuffer* buf,
                 int buf_len,
                 OnceCompletionCallback callback) override;

  // Enqueue expected writes.
  void ExpectWriteInfoOk(size_t len, bool async);
  void ExpectWriteInfo(size_t len, bool async, int result);
  void ExpectWriteDataOk(size_t len, bool async);
  void ExpectWriteData(size_t len, bool async, int result);

  // Complete a pending asynchronous write. This method DCHECKs unless there is
  // a pending write (a write for which WriteInfo() or WriteData() has been
  // called but the callback has not yet been run).
  void CompletePendingWrite();

  // Returns whether all expected reads have been consumed.
  bool AllExpectedWritesDone() { return expected_writes_.size() == 0; }

 private:
  struct ExpectedWrite {
    ExpectedWrite(bool is_info, size_t length, bool async, int result)
        : is_info(is_info), length(length), async(async), result(result) {}
    bool is_info;
    size_t length;
    bool async;
    int result;
  };

  base::queue<ExpectedWrite> expected_writes_;

  size_t info_written_;
  size_t data_written_;

  OnceCompletionCallback pending_callback_;

  DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseWriter);
};

}  // namespace content

#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_TEST_UTILS_H_
