// 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 NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_
#define NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_

#include "net/http/http_transaction.h"

#include <stdint.h>

#include <string>

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/net_error_details.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/base/test_completion_callback.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/socket/connection_attempts.h"

namespace net {

class HttpRequestHeaders;
class IOBuffer;
class SSLPrivateKey;
class X509Certificate;
class NetLogWithSource;
struct HttpRequestInfo;

//-----------------------------------------------------------------------------
// mock transaction data

// these flags may be combined to form the test_mode field
enum {
  TEST_MODE_NORMAL = 0,
  TEST_MODE_SYNC_NET_START = 1 << 0,
  TEST_MODE_SYNC_NET_READ  = 1 << 1,
  TEST_MODE_SYNC_CACHE_START = 1 << 2,
  TEST_MODE_SYNC_CACHE_READ  = 1 << 3,
  TEST_MODE_SYNC_CACHE_WRITE  = 1 << 4,
  TEST_MODE_SYNC_ALL = (TEST_MODE_SYNC_NET_START | TEST_MODE_SYNC_NET_READ |
                        TEST_MODE_SYNC_CACHE_START | TEST_MODE_SYNC_CACHE_READ |
                        TEST_MODE_SYNC_CACHE_WRITE),
  TEST_MODE_SLOW_READ = 1 << 5
};

using MockTransactionReadHandler = int (*)(int64_t content_length,
                                           int64_t offset,
                                           IOBuffer* buf,
                                           int buf_len);
using MockTransactionHandler = void (*)(const HttpRequestInfo* request,
                                        std::string* response_status,
                                        std::string* response_headers,
                                        std::string* response_data);

struct MockTransaction {
  const char* url;
  const char* method;
  // If |request_time| is unspecified, the current time will be used.
  base::Time request_time;
  const char* request_headers;
  int load_flags;
  const char* status;
  const char* response_headers;
  // If |response_time| is unspecified, the current time will be used.
  base::Time response_time;
  const char* data;
  int test_mode;
  MockTransactionHandler handler;
  MockTransactionReadHandler read_handler;
  scoped_refptr<X509Certificate> cert;
  CertStatus cert_status;
  int ssl_connection_status;
  // Value returned by MockNetworkTransaction::Start (potentially
  // asynchronously if |!(test_mode & TEST_MODE_SYNC_NET_START)|.)
  Error return_code;
};

extern const MockTransaction kSimpleGET_Transaction;
extern const MockTransaction kSimplePOST_Transaction;
extern const MockTransaction kTypicalGET_Transaction;
extern const MockTransaction kETagGET_Transaction;
extern const MockTransaction kRangeGET_Transaction;

// returns the mock transaction for the given URL
const MockTransaction* FindMockTransaction(const GURL& url);

// Add/Remove a mock transaction that can be accessed via FindMockTransaction.
// There can be only one MockTransaction associated with a given URL.
void AddMockTransaction(const MockTransaction* trans);
void RemoveMockTransaction(const MockTransaction* trans);

struct ScopedMockTransaction : MockTransaction {
  ScopedMockTransaction() {
    AddMockTransaction(this);
  }
  explicit ScopedMockTransaction(const MockTransaction& t)
      : MockTransaction(t) {
    AddMockTransaction(this);
  }
  ~ScopedMockTransaction() {
    RemoveMockTransaction(this);
  }
};

//-----------------------------------------------------------------------------
// mock http request

class MockHttpRequest : public HttpRequestInfo {
 public:
  explicit MockHttpRequest(const MockTransaction& t);
};

//-----------------------------------------------------------------------------
// use this class to test completely consuming a transaction

class TestTransactionConsumer {
 public:
  TestTransactionConsumer(RequestPriority priority,
                          HttpTransactionFactory* factory);
  virtual ~TestTransactionConsumer();

  void Start(const HttpRequestInfo* request, const NetLogWithSource& net_log);

  bool is_done() const { return state_ == DONE; }
  int error() const { return error_; }

  const HttpResponseInfo* response_info() const {
    return trans_->GetResponseInfo();
  }
  const HttpTransaction* transaction() const { return trans_.get(); }
  const std::string& content() const { return content_; }

 private:
  enum State {
    IDLE,
    STARTING,
    READING,
    DONE
  };

  void DidStart(int result);
  void DidRead(int result);
  void DidFinish(int result);
  void Read();

  void OnIOComplete(int result);

  State state_;
  std::unique_ptr<HttpTransaction> trans_;
  std::string content_;
  scoped_refptr<IOBuffer> read_buf_;
  int error_;

  static int quit_counter_;
};

//-----------------------------------------------------------------------------
// mock network layer

class MockNetworkLayer;

// This transaction class inspects the available set of mock transactions to
// find data for the request URL.  It supports IO operations that complete
// synchronously or asynchronously to help exercise different code paths in the
// HttpCache implementation.
class MockNetworkTransaction
    : public HttpTransaction,
      public base::SupportsWeakPtr<MockNetworkTransaction> {
  typedef WebSocketHandshakeStreamBase::CreateHelper CreateHelper;

 public:
  MockNetworkTransaction(RequestPriority priority, MockNetworkLayer* factory);
  ~MockNetworkTransaction() override;

  int Start(const HttpRequestInfo* request,
            const CompletionCallback& callback,
            const NetLogWithSource& net_log) override;

  int RestartIgnoringLastError(const CompletionCallback& callback) override;

  int RestartWithCertificate(X509Certificate* client_cert,
                             SSLPrivateKey* client_private_key,
                             const CompletionCallback& callback) override;

  int RestartWithAuth(const AuthCredentials& credentials,
                      const CompletionCallback& callback) override;

  bool IsReadyToRestartForAuth() override;

  int Read(IOBuffer* buf,
           int buf_len,
           const CompletionCallback& callback) override;
  void PopulateNetErrorDetails(NetErrorDetails* details) const override;

  void StopCaching() override;

  bool GetFullRequestHeaders(HttpRequestHeaders* headers) const override;

  int64_t GetTotalReceivedBytes() const override;

  int64_t GetTotalSentBytes() const override;

  void DoneReading() override;

  const HttpResponseInfo* GetResponseInfo() const override;

  LoadState GetLoadState() const override;

  void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;

  bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;

  bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;

  void SetPriority(RequestPriority priority) override;

  void SetWebSocketHandshakeStreamCreateHelper(
      CreateHelper* create_helper) override;

  void SetBeforeNetworkStartCallback(
      const BeforeNetworkStartCallback& callback) override;

  void SetBeforeHeadersSentCallback(
      const BeforeHeadersSentCallback& callback) override;

  int ResumeNetworkStart() override;

  void GetConnectionAttempts(ConnectionAttempts* out) const override;

  CreateHelper* websocket_handshake_stream_create_helper() {
    return websocket_handshake_stream_create_helper_;
  }
  RequestPriority priority() const { return priority_; }
  const HttpRequestInfo* request() const { return request_; }

  // Bogus value that will be returned by GetTotalReceivedBytes() if the
  // MockNetworkTransaction was started.
  static const int64_t kTotalReceivedBytes;
  // Bogus value that will be returned by GetTotalSentBytes() if the
  // MockNetworkTransaction was started.
  static const int64_t kTotalSentBytes;

 private:
  int StartInternal(const HttpRequestInfo* request,
                    const CompletionCallback& callback,
                    const NetLogWithSource& net_log);
  void CallbackLater(const CompletionCallback& callback, int result);
  void RunCallback(const CompletionCallback& callback, int result);

  const HttpRequestInfo* request_;
  HttpResponseInfo response_;
  std::string data_;
  int64_t data_cursor_;
  int64_t content_length_;
  int test_mode_;
  RequestPriority priority_;
  MockTransactionReadHandler read_handler_;
  CreateHelper* websocket_handshake_stream_create_helper_;
  BeforeNetworkStartCallback before_network_start_callback_;
  base::WeakPtr<MockNetworkLayer> transaction_factory_;
  int64_t received_bytes_;
  int64_t sent_bytes_;

  // NetLog ID of the fake / non-existent underlying socket used by the
  // connection. Requires Start() be passed a NetLogWithSource with a real
  // NetLog to
  // be initialized.
  unsigned int socket_log_id_;

  bool done_reading_called_;

  base::WeakPtrFactory<MockNetworkTransaction> weak_factory_;

};

class MockNetworkLayer : public HttpTransactionFactory,
                         public base::SupportsWeakPtr<MockNetworkLayer> {
 public:
  MockNetworkLayer();
  ~MockNetworkLayer() override;

  int transaction_count() const { return transaction_count_; }
  bool done_reading_called() const { return done_reading_called_; }
  bool stop_caching_called() const { return stop_caching_called_; }
  void TransactionDoneReading();
  void TransactionStopCaching();

  // Resets the transaction count. Can be called after test setup in order to
  // make test expectations independent of how test setup is performed.
  void ResetTransactionCount();

  // Returns the last priority passed to CreateTransaction, or
  // DEFAULT_PRIORITY if it hasn't been called yet.
  RequestPriority last_create_transaction_priority() const {
    return last_create_transaction_priority_;
  }

  // Returns the last transaction created by
  // CreateTransaction. Returns a NULL WeakPtr if one has not been
  // created yet, or the last transaction has been destroyed, or
  // ClearLastTransaction() has been called and a new transaction
  // hasn't been created yet.
  base::WeakPtr<MockNetworkTransaction> last_transaction() {
    return last_transaction_;
  }

  // Makes last_transaction() return NULL until the next transaction
  // is created.
  void ClearLastTransaction() {
    last_transaction_.reset();
  }

  // HttpTransactionFactory:
  int CreateTransaction(RequestPriority priority,
                        std::unique_ptr<HttpTransaction>* trans) override;
  HttpCache* GetCache() override;
  HttpNetworkSession* GetSession() override;

  // The caller must guarantee that |clock| will outlive this object.
  void SetClock(base::Clock* clock);
  base::Clock* clock() const { return clock_; }

  // The current time (will use clock_ if it is non NULL).
  base::Time Now();

 private:
  int transaction_count_;
  bool done_reading_called_;
  bool stop_caching_called_;
  RequestPriority last_create_transaction_priority_;

  // By default clock_ is NULL but it can be set to a custom clock by test
  // frameworks using SetClock.
  base::Clock* clock_;

  base::WeakPtr<MockNetworkTransaction> last_transaction_;
};

//-----------------------------------------------------------------------------
// helpers

// read the transaction completely
int ReadTransaction(HttpTransaction* trans, std::string* result);

}  // namespace net

#endif  // NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_
