// 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,
                    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_
