// 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_SPDY_SPDY_STREAM_H_
#define NET_SPDY_SPDY_STREAM_H_

#include <list>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "googleurl/src/gurl.h"
#include "net/base/bandwidth_metrics.h"
#include "net/base/io_buffer.h"
#include "net/base/net_export.h"
#include "net/base/net_log.h"
#include "net/base/request_priority.h"
#include "net/base/server_bound_cert_service.h"
#include "net/base/ssl_client_cert_type.h"
#include "net/socket/ssl_client_socket.h"
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_header_block.h"
#include "net/spdy/spdy_protocol.h"
#include "net/spdy/spdy_session.h"

namespace net {

class AddressList;
class IPEndPoint;
class SSLCertRequestInfo;
class SSLInfo;

// The SpdyStream is used by the SpdySession to represent each stream known
// on the SpdySession.  This class provides interfaces for SpdySession to use.
// Streams can be created either by the client or by the server.  When they
// are initiated by the client, both the SpdySession and client object (such as
// a SpdyNetworkTransaction) will maintain a reference to the stream.  When
// initiated by the server, only the SpdySession will maintain any reference,
// until such a time as a client object requests a stream for the path.
class NET_EXPORT_PRIVATE SpdyStream
    : public base::RefCounted<SpdyStream> {
 public:
  // Delegate handles protocol specific behavior of spdy stream.
  class NET_EXPORT_PRIVATE Delegate {
   public:
    Delegate() {}

    // Called when SYN frame has been sent.
    // Returns true if no more data to be sent after SYN frame.
    virtual bool OnSendHeadersComplete(int status) = 0;

    // Called when stream is ready to send data.
    // Returns network error code. OK when it successfully sent data.
    // ERR_IO_PENDING when performing operation asynchronously.
    virtual int OnSendBody() = 0;

    // Called when data has been sent. |status| indicates network error
    // or number of bytes that has been sent. On return, |eof| is set to true
    // if no more data is available to send in the request body.
    // Returns network error code. OK when it successfully sent data.
    virtual int OnSendBodyComplete(int status, bool* eof) = 0;

    // Called when the SYN_STREAM, SYN_REPLY, or HEADERS frames are received.
    // Normal streams will receive a SYN_REPLY and optional HEADERS frames.
    // Pushed streams will receive a SYN_STREAM and optional HEADERS frames.
    // Because a stream may have a SYN_* frame and multiple HEADERS frames,
    // this callback may be called multiple times.
    // |status| indicates network error. Returns network error code.
    virtual int OnResponseReceived(const SpdyHeaderBlock& response,
                                   base::Time response_time,
                                   int status) = 0;

    // Called when a HEADERS frame is sent.
    virtual void OnHeadersSent() = 0;

    // Called when data is received.
    // Returns network error code. OK when it successfully receives data.
    virtual int OnDataReceived(const char* data, int length) = 0;

    // Called when data is sent.
    virtual void OnDataSent(int length) = 0;

    // Called when SpdyStream is closed.
    virtual void OnClose(int status) = 0;

   protected:
    virtual ~Delegate() {}

   private:
    DISALLOW_COPY_AND_ASSIGN(Delegate);
  };

  // Indicates pending frame type.
  enum FrameType {
    TYPE_HEADERS,
    TYPE_DATA
  };

  // Structure to contains pending frame information.
  typedef struct {
    FrameType type;
    union {
      SpdyHeaderBlock* header_block;
      SpdyDataFrame* data_frame;
    };
  } PendingFrame;

  // SpdyStream constructor
  SpdyStream(SpdySession* session,
             bool pushed,
             const BoundNetLog& net_log);

  // Set new |delegate|. |delegate| must not be NULL.
  // If it already received SYN_REPLY or data, OnResponseReceived() or
  // OnDataReceived() will be called.
  void SetDelegate(Delegate* delegate);
  Delegate* GetDelegate() { return delegate_; }

  // Detach delegate from the stream. It will cancel the stream if it was not
  // cancelled yet.  It is safe to call multiple times.
  void DetachDelegate();

  // Is this stream a pushed stream from the server.
  bool pushed() const { return pushed_; }

  SpdyStreamId stream_id() const { return stream_id_; }
  void set_stream_id(SpdyStreamId stream_id) { stream_id_ = stream_id; }

  bool response_received() const { return response_received_; }
  void set_response_received() { response_received_ = true; }

  // For pushed streams, we track a path to identify them.
  const std::string& path() const { return path_; }
  void set_path(const std::string& path) { path_ = path; }

  RequestPriority priority() const { return priority_; }
  void set_priority(RequestPriority priority) { priority_ = priority; }

  int32 send_window_size() const { return send_window_size_; }
  void set_send_window_size(int32 window_size) {
    send_window_size_ = window_size;
  }

  int32 recv_window_size() const { return recv_window_size_; }
  void set_recv_window_size(int32 window_size) {
    recv_window_size_ = window_size;
  }

  // Set session_'s initial_recv_window_size. Used by unittests.
  void set_initial_recv_window_size(int32 window_size);

  bool stalled_by_flow_control() { return stalled_by_flow_control_; }

  void set_stalled_by_flow_control(bool stalled) {
    stalled_by_flow_control_ = stalled;
  }

  // Adjusts the |send_window_size_| by |delta_window_size|. |delta_window_size|
  // is the difference between the SETTINGS_INITIAL_WINDOW_SIZE in SETTINGS
  // frame and the previous initial_send_window_size.
  void AdjustSendWindowSize(int32 delta_window_size);

  // Increases |send_window_size_| with delta extracted from a WINDOW_UPDATE
  // frame; sends a RST_STREAM if delta overflows |send_window_size_| and
  // removes the stream from the session.
  void IncreaseSendWindowSize(int32 delta_window_size);

  // Decreases |send_window_size_| by the given number of bytes.
  void DecreaseSendWindowSize(int32 delta_window_size);

  int GetPeerAddress(IPEndPoint* address) const;
  int GetLocalAddress(IPEndPoint* address) const;

  // Returns true if the underlying transport socket ever had any reads or
  // writes.
  bool WasEverUsed() const;

  // Increases |recv_window_size_| by the given number of bytes, also sends
  // a WINDOW_UPDATE frame.
  void IncreaseRecvWindowSize(int32 delta_window_size);

  // Decreases |recv_window_size_| by the given number of bytes, called
  // whenever data is read.  May also send a RST_STREAM and remove the
  // stream from the session if the resultant |recv_window_size_| is
  // negative, since that would be a flow control violation.
  void DecreaseRecvWindowSize(int32 delta_window_size);

  const BoundNetLog& net_log() const { return net_log_; }

  const SpdyHeaderBlock& spdy_headers() const;
  void set_spdy_headers(scoped_ptr<SpdyHeaderBlock> headers);
  base::Time GetRequestTime() const;
  void SetRequestTime(base::Time t);

  // Called by the SpdySession when a response (e.g. a SYN_STREAM or SYN_REPLY)
  // has been received for this stream. Returns a status code.
  int OnResponseReceived(const SpdyHeaderBlock& response);

  // Called by the SpdySession when late-bound headers are received for a
  // stream. Returns a status code.
  int OnHeaders(const SpdyHeaderBlock& headers);

  // Called by the SpdySession when response data has been received for this
  // stream.  This callback may be called multiple times as data arrives
  // from the network, and will never be called prior to OnResponseReceived.
  // |buffer| contains the data received.  The stream must copy any data
  //          from this buffer before returning from this callback.
  // |length| is the number of bytes received or an error.
  //         A zero-length count does not indicate end-of-stream.
  void OnDataReceived(const char* buffer, int bytes);

  // Called by the SpdySession when a write has completed.  This callback
  // will be called multiple times for each write which completes.  Writes
  // include the SYN_STREAM write and also DATA frame writes.
  // |result| is the number of bytes written or a net error code.
  void OnWriteComplete(int bytes);

  // Called by the SpdySession when the request is finished.  This callback
  // will always be called at the end of the request and signals to the
  // stream that the stream has no more network events.  No further callbacks
  // to the stream will be made after this call.
  // |status| is an error code or OK.
  void OnClose(int status);

  // Called by the SpdySession to log stream related errors.
  void LogStreamError(int status, const std::string& description);

  void Cancel();
  void Close();
  bool cancelled() const { return cancelled_; }
  bool closed() const { return io_state_ == STATE_DONE; }
  // TODO(satorux): This is only for testing. We should be able to remove
  // this once crbug.com/113107 is addressed.
  bool body_sent() const { return io_state_ > STATE_SEND_BODY_COMPLETE; }

  // Interface for Spdy[Http|WebSocket]Stream to use.

  // Sends the request.
  // For non push stream, it will send SYN_STREAM frame.
  int SendRequest(bool has_upload_data);

  // Sends a HEADERS frame. SpdyStream owns |headers| and will release it after
  // the HEADERS frame is actually sent.
  int WriteHeaders(SpdyHeaderBlock* headers);

  // Sends DATA frame.
  int WriteStreamData(IOBuffer* data, int length,
                      SpdyDataFlags flags);

  // Fills SSL info in |ssl_info| and returns true when SSL is in use.
  bool GetSSLInfo(SSLInfo* ssl_info,
                  bool* was_npn_negotiated,
                  NextProto* protocol_negotiated);

  // Fills SSL Certificate Request info |cert_request_info| and returns
  // true when SSL is in use.
  bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);

  bool is_idle() const {
    return io_state_ == STATE_OPEN || io_state_ == STATE_DONE;
  }

  int response_status() const { return response_status_; }

  // Returns true if the URL for this stream is known.
  bool HasUrl() const;

  // Get the URL associated with this stream.  Only valid when has_url() is
  // true.
  GURL GetUrl() const;

  int GetProtocolVersion() const;

 private:
  class SpdyStreamIOBufferProducer;

  enum State {
    STATE_NONE,
    STATE_GET_DOMAIN_BOUND_CERT,
    STATE_GET_DOMAIN_BOUND_CERT_COMPLETE,
    STATE_SEND_DOMAIN_BOUND_CERT,
    STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE,
    STATE_SEND_HEADERS,
    STATE_SEND_HEADERS_COMPLETE,
    STATE_SEND_BODY,
    STATE_SEND_BODY_COMPLETE,
    STATE_WAITING_FOR_RESPONSE,
    STATE_OPEN,
    STATE_DONE
  };

  friend class base::RefCounted<SpdyStream>;

  virtual ~SpdyStream();

  // If the stream is stalled and if |send_window_size_| is positive, then set
  // |stalled_by_flow_control_| to false and unstall the stream.
  void PossiblyResumeIfStalled();

  void OnGetDomainBoundCertComplete(int result);

  // Try to make progress sending/receiving the request/response.
  int DoLoop(int result);

  // The implementations of each state of the state machine.
  int DoGetDomainBoundCert();
  int DoGetDomainBoundCertComplete(int result);
  int DoSendDomainBoundCert();
  int DoSendDomainBoundCertComplete(int result);
  int DoSendHeaders();
  int DoSendHeadersComplete(int result);
  int DoSendBody();
  int DoSendBodyComplete(int result);
  int DoReadHeaders();
  int DoReadHeadersComplete(int result);
  int DoOpen(int result);

  // Update the histograms.  Can safely be called repeatedly, but should only
  // be called after the stream has completed.
  void UpdateHistograms();

  // When a server pushed stream is first created, this function is posted on
  // the MessageLoop to replay all the data that the server has already sent.
  void PushedStreamReplayData();

  // Informs the SpdySession that this stream has a write available.
  void SetHasWriteAvailable();

  // Returns a newly created SPDY frame owned by the called that contains
  // the next frame to be sent by this frame.  May return NULL if this
  // stream has become stalled on flow control.
  SpdyFrame* ProduceNextFrame();

  // There is a small period of time between when a server pushed stream is
  // first created, and the pushed data is replayed. Any data received during
  // this time should continue to be buffered.
  bool continue_buffering_data_;

  SpdyStreamId stream_id_;
  std::string path_;
  RequestPriority priority_;
  size_t slot_;

  // Flow control variables.
  bool stalled_by_flow_control_;
  int32 send_window_size_;
  int32 recv_window_size_;
  int32 unacked_recv_window_bytes_;

  const bool pushed_;
  ScopedBandwidthMetrics metrics_;
  bool response_received_;

  scoped_refptr<SpdySession> session_;

  // The transaction should own the delegate.
  SpdyStream::Delegate* delegate_;

  // The request to send.
  scoped_ptr<SpdyHeaderBlock> request_;

  // The time at which the request was made that resulted in this response.
  // For cached responses, this time could be "far" in the past.
  base::Time request_time_;

  scoped_ptr<SpdyHeaderBlock> response_;
  base::Time response_time_;

  // An in order list of pending frame data that are going to be sent. HEADERS
  // frames are queued as SpdyHeaderBlock structures because these must be
  // compressed just before sending. Data frames are queued as SpdyDataFrame.
  std::list<PendingFrame> pending_frames_;

  // An in order list of sending frame types. It will be used to know which type
  // of frame is sent and which callback should be invoked in OnOpen().
  std::list<FrameType> waiting_completions_;

  State io_state_;

  // Since we buffer the response, we also buffer the response status.
  // Not valid until the stream is closed.
  int response_status_;

  bool cancelled_;
  bool has_upload_data_;

  BoundNetLog net_log_;

  base::TimeTicks send_time_;
  base::TimeTicks recv_first_byte_time_;
  base::TimeTicks recv_last_byte_time_;
  int send_bytes_;
  int recv_bytes_;
  // Data received before delegate is attached.
  std::vector<scoped_refptr<IOBufferWithSize> > pending_buffers_;

  SSLClientCertType domain_bound_cert_type_;
  std::string domain_bound_private_key_;
  std::string domain_bound_cert_;
  ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_;

  DISALLOW_COPY_AND_ASSIGN(SpdyStream);
};

}  // namespace net

#endif  // NET_SPDY_SPDY_STREAM_H_
