// 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_HTTP_HTTP_PIPELINED_CONNECTION_IMPL_H_
#define NET_HTTP_HTTP_PIPELINED_CONNECTION_IMPL_H_

#include <map>
#include <queue>
#include <string>

#include "base/basictypes.h"
#include "base/location.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/weak_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/base/net_log.h"
#include "net/base/ssl_config_service.h"
#include "net/http/http_pipelined_connection.h"
#include "net/http/http_request_info.h"
#include "net/http/http_stream_parser.h"
#include "net/proxy/proxy_info.h"

namespace net {

class ClientSocketHandle;
class GrowableIOBuffer;
class HostPortPair;
class HttpNetworkSession;
class HttpRequestHeaders;
class HttpResponseInfo;
class IOBuffer;
class SSLCertRequestInfo;
class SSLInfo;

// This class manages all of the state for a single pipelined connection. It
// tracks the order that HTTP requests are sent and enforces that the
// subsequent reads occur in the appropriate order.
//
// If an error occurs related to pipelining, ERR_PIPELINE_EVICTION will be
// returned to the client. This indicates the client should retry the request
// without pipelining.
class NET_EXPORT_PRIVATE HttpPipelinedConnectionImpl
    : public HttpPipelinedConnection {
 public:
  class Factory : public HttpPipelinedConnection::Factory {
   public:
    virtual HttpPipelinedConnection* CreateNewPipeline(
        ClientSocketHandle* connection,
        HttpPipelinedConnection::Delegate* delegate,
        const HostPortPair& origin,
        const SSLConfig& used_ssl_config,
        const ProxyInfo& used_proxy_info,
        const BoundNetLog& net_log,
        bool was_npn_negotiated,
        NextProto protocol_negotiated) override;
  };

  HttpPipelinedConnectionImpl(ClientSocketHandle* connection,
                              Delegate* delegate,
                              const HostPortPair& origin,
                              const SSLConfig& used_ssl_config,
                              const ProxyInfo& used_proxy_info,
                              const BoundNetLog& net_log,
                              bool was_npn_negotiated,
                              NextProto protocol_negotiated);
  virtual ~HttpPipelinedConnectionImpl();

  // HttpPipelinedConnection interface.

  // Used by HttpStreamFactoryImpl and friends.
  virtual HttpPipelinedStream* CreateNewStream() override;

  // Used by HttpPipelinedHost.
  virtual int depth() const override;
  virtual bool usable() const override;
  virtual bool active() const override;

  // Used by HttpStreamFactoryImpl.
  virtual const SSLConfig& used_ssl_config() const override;
  virtual const ProxyInfo& used_proxy_info() const override;
  virtual const BoundNetLog& net_log() const override;
  virtual bool was_npn_negotiated() const override;
  virtual NextProto protocol_negotiated() const override;

  // Used by HttpPipelinedStream.

  // Notifies this pipeline that a stream is no longer using it.
  void OnStreamDeleted(int pipeline_id);

  // Effective implementation of HttpStream. Note that we don't directly
  // implement that interface. Instead, these functions will be called by the
  // pass-through methods in HttpPipelinedStream.
  void InitializeParser(int pipeline_id,
                        const HttpRequestInfo* request,
                        const BoundNetLog& net_log);

  int SendRequest(int pipeline_id,
                  const std::string& request_line,
                  const HttpRequestHeaders& headers,
                  HttpResponseInfo* response,
                  const CompletionCallback& callback);

  int ReadResponseHeaders(int pipeline_id,
                          const CompletionCallback& callback);

  int ReadResponseBody(int pipeline_id,
                       IOBuffer* buf, int buf_len,
                       const CompletionCallback& callback);

  void Close(int pipeline_id,
             bool not_reusable);

  UploadProgress GetUploadProgress(int pipeline_id) const;

  HttpResponseInfo* GetResponseInfo(int pipeline_id);

  bool IsResponseBodyComplete(int pipeline_id) const;

  bool CanFindEndOfResponse(int pipeline_id) const;

  bool IsMoreDataBuffered(int pipeline_id) const;

  bool IsConnectionReused(int pipeline_id) const;

  void SetConnectionReused(int pipeline_id);

  void GetSSLInfo(int pipeline_id,
                  SSLInfo* ssl_info);

  void GetSSLCertRequestInfo(int pipeline_id,
                             SSLCertRequestInfo* cert_request_info);

  // Attempts to drain the response body for |stream| so that the pipeline may
  // be reused.
  void Drain(HttpPipelinedStream* stream, HttpNetworkSession* session);

 private:
  enum StreamState {
    STREAM_CREATED,
    STREAM_BOUND,
    STREAM_SENDING,
    STREAM_SENT,
    STREAM_READ_PENDING,
    STREAM_ACTIVE,
    STREAM_CLOSED,
    STREAM_READ_EVICTED,
    STREAM_UNUSED,
  };
  enum SendRequestState {
    SEND_STATE_START_IMMEDIATELY,
    SEND_STATE_START_NEXT_DEFERRED_REQUEST,
    SEND_STATE_SEND_ACTIVE_REQUEST,
    SEND_STATE_COMPLETE,
    SEND_STATE_EVICT_PENDING_REQUESTS,
    SEND_STATE_NONE,
  };
  enum ReadHeadersState {
    READ_STATE_START_IMMEDIATELY,
    READ_STATE_START_NEXT_DEFERRED_READ,
    READ_STATE_READ_HEADERS,
    READ_STATE_READ_HEADERS_COMPLETE,
    READ_STATE_WAITING_FOR_CLOSE,
    READ_STATE_STREAM_CLOSED,
    READ_STATE_NONE,
    READ_STATE_EVICT_PENDING_READS,
  };

  struct PendingSendRequest {
    PendingSendRequest();
    ~PendingSendRequest();

    int pipeline_id;
    std::string request_line;
    HttpRequestHeaders headers;
    HttpResponseInfo* response;
    CompletionCallback callback;
  };

  struct StreamInfo {
    StreamInfo();
    ~StreamInfo();

    linked_ptr<HttpStreamParser> parser;
    CompletionCallback read_headers_callback;
    CompletionCallback pending_user_callback;
    StreamState state;
    NetLog::Source source;
  };

  typedef std::map<int, StreamInfo> StreamInfoMap;

  // Called after the first request is sent or in a task sometime after the
  // first stream is added to this pipeline. This gives the first request
  // priority to send, but doesn't hold up other requests if it doesn't.
  // When called the first time, notifies the |delegate_| that we can accept new
  // requests.
  void ActivatePipeline();

  // Responsible for sending one request at a time and waiting until each
  // comepletes.
  int DoSendRequestLoop(int result);

  // Called when an asynchronous Send() completes.
  void OnSendIOCallback(int result);

  // Activates the only request in |pending_send_request_queue_|. This should
  // only be called via SendRequest() when the send loop is idle.
  int DoStartRequestImmediately(int result);

  // Activates the first request in |pending_send_request_queue_| that hasn't
  // been closed, if any. This is called via DoSendComplete() after a prior
  // request complets.
  int DoStartNextDeferredRequest(int result);

  // Sends the active request.
  int DoSendActiveRequest(int result);

  // Notifies the user that the send has completed. This may be called directly
  // after SendRequest() for a synchronous request, or it may be called in
  // response to OnSendIOCallback for an asynchronous request.
  int DoSendComplete(int result);

  // Evicts all unsent deferred requests. This is called if there is a Send()
  // error or one of our streams informs us the connection is no longer
  // reusable.
  int DoEvictPendingSendRequests(int result);

  // Ensures that only the active request's HttpPipelinedSocket can read from
  // the underlying socket until it completes. A HttpPipelinedSocket informs us
  // that it's done by calling Close().
  int DoReadHeadersLoop(int result);

  // Called when the pending asynchronous ReadResponseHeaders() completes.
  void OnReadIOCallback(int result);

  // Invokes DoStartNextDeferredRead() if the read loop is idle. This is called
  // via a task queued when the previous |active_read_id_| closes its stream
  // after a succesful response.
  void StartNextDeferredRead();

  // Activates the next read request immediately. This is called via
  // ReadResponseHeaders() if that stream is at the front of |request_order_|
  // and the read loop is idle.
  int DoStartReadImmediately(int result);

  // Activates the next read request in |request_order_| if it's ready to go.
  // This is called via StartNextDeferredRead().
  int DoStartNextDeferredRead(int result);

  // Calls ReadResponseHeaders() on the active request's parser.
  int DoReadHeaders(int result);

  // Notifies the user that reading the headers has completed. This may happen
  // directly after DoReadNextHeaders() if the response is already available.
  // Otherwise, it is called in response to OnReadIOCallback().
  int DoReadHeadersComplete(int result);

  // Halts the read loop until Close() is called by the active stream.
  int DoReadWaitForClose(int result);

  // Cleans up the state associated with the active request. Invokes
  // DoReadNextHeaders() in a new task to start the next response. This is
  // called after the active request's HttpPipelinedSocket calls Close().
  int DoReadStreamClosed();

  // Removes all pending ReadResponseHeaders() requests from the queue. This may
  // happen if there is an error with the pipeline or one of our
  // HttpPipelinedSockets indicates the connection was suddenly closed.
  int DoEvictPendingReadHeaders(int result);

  // Determines if the response headers indicate pipelining will work. This is
  // called every time we receive headers.
  void CheckHeadersForPipelineCompatibility(int pipeline_id, int result);

  // Reports back to |delegate_| whether pipelining will work.
  void ReportPipelineFeedback(int pipeline_id, Feedback feedback);

  // Posts a task to fire the user's callback in response to SendRequest() or
  // ReadResponseHeaders() completing on an underlying parser. This might be
  // invoked in response to our own IO callbacks, or it may be invoked if the
  // underlying parser completes SendRequest() or ReadResponseHeaders()
  // synchronously, but we've already returned ERR_IO_PENDING to the user's
  // SendRequest() or ReadResponseHeaders() call into us.
  void QueueUserCallback(int pipeline_id,
                         const CompletionCallback& callback,
                         int rv,
                         const tracked_objects::Location& from_here);

  // Invokes the callback queued in QueueUserCallback().
  void FireUserCallback(int pipeline_id, int result);

  Delegate* delegate_;
  scoped_ptr<ClientSocketHandle> connection_;
  SSLConfig used_ssl_config_;
  ProxyInfo used_proxy_info_;
  BoundNetLog net_log_;
  bool was_npn_negotiated_;
  // Protocol negotiated with the server.
  NextProto protocol_negotiated_;
  scoped_refptr<GrowableIOBuffer> read_buf_;
  int next_pipeline_id_;
  bool active_;
  bool usable_;
  bool completed_one_request_;
  base::WeakPtrFactory<HttpPipelinedConnectionImpl> weak_factory_;

  StreamInfoMap stream_info_map_;

  std::queue<int> request_order_;

  std::queue<PendingSendRequest*> pending_send_request_queue_;
  scoped_ptr<PendingSendRequest> active_send_request_;
  SendRequestState send_next_state_;
  bool send_still_on_call_stack_;

  ReadHeadersState read_next_state_;
  int active_read_id_;
  bool read_still_on_call_stack_;

  DISALLOW_COPY_AND_ASSIGN(HttpPipelinedConnectionImpl);
};

}  // namespace net

#endif  // NET_HTTP_HTTP_PIPELINED_CONNECTION_IMPL_H_
