// Copyright (c) 2012 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_URL_REQUEST_URL_REQUEST_TEST_JOB_H_
#define NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_

#include <string>

#include "base/memory/weak_ptr.h"
#include "net/base/load_timing_info.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory.h"

namespace net {

// This job type is designed to help with simple unit tests. To use, you
// probably want to inherit from it to set up the state you want. Then install
// it as the protocol handler for the "test" scheme.
//
// It will respond to several URLs, which you can retrieve using the test_url*
// getters, which will in turn respond with the corresponding responses returned
// by test_data*. Any other URLs that begin with "test:" will return an error,
// which might also be useful, you can use test_url_error() to retreive a
// standard one.
//
// You can override the known URLs or the response data by overriding Start().
//
// Optionally, you can also construct test jobs to return a headers and data
// provided to the contstructor in response to any request url.
//
// When a job is created, it gets put on a queue of pending test jobs. To
// process jobs on this queue, use ProcessOnePendingMessage, which will process
// one step of the next job. If the job is incomplete, it will be added to the
// end of the queue.
//
// Optionally, you can also construct test jobs that advance automatically
// without having to call ProcessOnePendingMessage.
class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob {
 public:
  // Constructs a job to return one of the canned responses depending on the
  // request url, with auto advance disabled.
  URLRequestTestJob(URLRequest* request, NetworkDelegate* network_delegate);

  // Constructs a job to return one of the canned responses depending on the
  // request url, optionally with auto advance enabled.
  URLRequestTestJob(URLRequest* request,
                    NetworkDelegate* network_delegate,
                    bool auto_advance);

  // Constructs a job to return the given response regardless of the request
  // url. The headers should include the HTTP status line and be formatted as
  // expected by HttpResponseHeaders.
  URLRequestTestJob(URLRequest* request,
                    net::NetworkDelegate* network_delegate,
                    const std::string& response_headers,
                    const std::string& response_data,
                    bool auto_advance);

  // The canned URLs this handler will respond to without having been
  // explicitly initialized with response headers and data.
  // FIXME(brettw): we should probably also have a redirect one
  static GURL test_url_1();
  static GURL test_url_2();
  static GURL test_url_3();
  static GURL test_url_4();
  static GURL test_url_error();
  static GURL test_url_redirect_to_url_2();

  // The data that corresponds to each of the URLs above
  static std::string test_data_1();
  static std::string test_data_2();
  static std::string test_data_3();
  static std::string test_data_4();

  // The headers that correspond to each of the URLs above
  static std::string test_headers();

  // The headers for a redirect response
  static std::string test_redirect_headers();

  // The headers for a redirect response to the second test url.
  static std::string test_redirect_to_url_2_headers();

  // The headers for a server error response
  static std::string test_error_headers();

  // Processes one pending message from the stack, returning true if any
  // message was processed, or false if there are no more pending request
  // notifications to send. This is not applicable when using auto_advance.
  static bool ProcessOnePendingMessage();

  // With auto advance enabled, the job will advance thru the stages without
  // the caller having to call ProcessOnePendingMessage. Auto advance depends
  // on having a message loop running. The default is to not auto advance.
  // Should not be altered after the job has started.
  bool auto_advance() { return auto_advance_; }
  void set_auto_advance(bool auto_advance) { auto_advance_ = auto_advance; }

  void set_load_timing_info(const LoadTimingInfo& load_timing_info) {
    load_timing_info_ = load_timing_info;
  }

  RequestPriority priority() const { return priority_; }

  // Create a protocol handler for callers that don't subclass.
  static URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler();

  // Job functions
  void SetPriority(RequestPriority priority) override;
  void Start() override;
  bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
  void Kill() override;
  bool GetMimeType(std::string* mime_type) const override;
  void GetResponseInfo(HttpResponseInfo* info) override;
  void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
  int GetResponseCode() const override;
  bool IsRedirectResponse(GURL* location, int* http_status_code) override;

 protected:
  // Override to specify whether the next read done from this job will
  // return IO pending.  This controls whether or not the WAITING state will
  // transition back to WAITING or to DATA_AVAILABLE after an asynchronous
  // read is processed.
  virtual bool NextReadAsync();

  // This is what operation we are going to do next when this job is handled.
  // When the stage is DONE, this job will not be put on the queue.
  enum Stage { WAITING, DATA_AVAILABLE, ALL_DATA, DONE };

  ~URLRequestTestJob() override;

  // Call to process the next opeation, usually sending a notification, and
  // advancing the stage if necessary. THIS MAY DELETE THE OBJECT.
  void ProcessNextOperation();

  // Call to move the job along to the next operation.
  void AdvanceJob();

  // Called via InvokeLater to cause callbacks to occur after Start() returns.
  virtual void StartAsync();

  bool auto_advance_;

  Stage stage_;

  RequestPriority priority_;

  // The headers the job should return, will be set in Start() if not provided
  // in the explicit ctor.
  scoped_refptr<HttpResponseHeaders> response_headers_;

  // The data to send, will be set in Start() if not provided in the explicit
  // ctor.
  std::string response_data_;

  // current offset within response_data_
  int offset_;

  // Holds the buffer for an asynchronous ReadRawData call
  IOBuffer* async_buf_;
  int async_buf_size_;

  LoadTimingInfo load_timing_info_;

  base::WeakPtrFactory<URLRequestTestJob> weak_factory_;
};

}  // namespace net

#endif  // NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_
