// Copyright (c) 2015 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_QUIC_QUIC_SPDY_SESSION_H_
#define NET_QUIC_QUIC_SPDY_SESSION_H_

#include <stddef.h>

#include <memory>

#include "base/macros.h"
#include "net/quic/quic_header_list.h"
#include "net/quic/quic_headers_stream.h"
#include "net/quic/quic_session.h"
#include "net/quic/quic_spdy_stream.h"

namespace net {

namespace test {
class QuicSpdySessionPeer;
}  // namespace test

// A QUIC session with a headers stream.
class NET_EXPORT_PRIVATE QuicSpdySession : public QuicSession {
 public:
  QuicSpdySession(QuicConnection* connection, const QuicConfig& config);

  ~QuicSpdySession() override;

  void Initialize() override;

  // Called by |headers_stream_| when headers have been received for a stream.
  virtual void OnStreamHeaders(QuicStreamId stream_id,
                               base::StringPiece headers_data);
  // Called by |headers_stream_| when headers with a priority have been
  // received for this stream.  This method will only be called for server
  // streams.
  virtual void OnStreamHeadersPriority(QuicStreamId stream_id,
                                       SpdyPriority priority);
  // Called by |headers_stream_| when headers have been completely received
  // for a stream.  |fin| will be true if the fin flag was set in the headers
  // frame.
  virtual void OnStreamHeadersComplete(QuicStreamId stream_id,
                                       bool fin,
                                       size_t frame_len);

  // Called by |headers_stream_| when headers have been completely received
  // for a stream.  |fin| will be true if the fin flag was set in the headers
  // frame.
  virtual void OnStreamHeaderList(QuicStreamId stream_id,
                                  bool fin,
                                  size_t frame_len,
                                  const QuicHeaderList& header_list);

  // Called by |headers_stream_| when push promise headers have been
  // received for a stream.
  virtual void OnPromiseHeaders(QuicStreamId stream_id,
                                base::StringPiece headers_data);

  // Called by |headers_stream_| when push promise headers have been
  // completely received.  |fin| will be true if the fin flag was set
  // in the headers.
  virtual void OnPromiseHeadersComplete(QuicStreamId stream_id,
                                        QuicStreamId promised_stream_id,
                                        size_t frame_len);

  // Called by |headers_stream_| when push promise headers have been
  // completely received.  |fin| will be true if the fin flag was set
  // in the headers.
  virtual void OnPromiseHeaderList(QuicStreamId stream_id,
                                   QuicStreamId promised_stream_id,
                                   size_t frame_len,
                                   const QuicHeaderList& header_list);

  // Writes |headers| for the stream |id| to the dedicated headers stream.
  // If |fin| is true, then no more data will be sent for the stream |id|.
  // If provided, |ack_notifier_delegate| will be registered to be notified when
  // we have seen ACKs for all packets resulting from this call.
  virtual size_t WriteHeaders(QuicStreamId id,
                              SpdyHeaderBlock headers,
                              bool fin,
                              SpdyPriority priority,
                              QuicAckListenerInterface* ack_notifier_delegate);

  QuicHeadersStream* headers_stream() { return headers_stream_.get(); }

  // Called when Head of Line Blocking happens in the headers stream.
  // |delta| indicates how long that piece of data has been blocked.
  virtual void OnHeadersHeadOfLineBlocking(QuicTime::Delta delta);

  // Called by the stream on creation to set priority in the write blocked list.
  void RegisterStreamPriority(QuicStreamId id, SpdyPriority priority);
  // Called by the stream on deletion to clear priority crom the write blocked
  // list.
  void UnregisterStreamPriority(QuicStreamId id);
  // Called by the stream on SetPriority to update priority on the write blocked
  // list.
  void UpdateStreamPriority(QuicStreamId id, SpdyPriority new_priority);

  void OnConfigNegotiated() override;

  // Called by |headers_stream_| when |force_hol_blocking_| is true.
  virtual void OnStreamFrameData(QuicStreamId stream_id,
                                 const char* data,
                                 size_t len,
                                 bool fin);

  bool force_hol_blocking() const { return force_hol_blocking_; }

 protected:
  // Override CreateIncomingDynamicStream() and CreateOutgoingDynamicStream()
  // with QuicSpdyStream return type to make sure that all data streams are
  // QuicSpdyStreams.
  QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override = 0;
  QuicSpdyStream* CreateOutgoingDynamicStream(SpdyPriority priority) override =
      0;

  QuicSpdyStream* GetSpdyDataStream(const QuicStreamId stream_id);

  // If an incoming stream can be created, return true.
  virtual bool ShouldCreateIncomingDynamicStream(QuicStreamId id) = 0;

  // If an outgoing stream can be created, return true.
  virtual bool ShouldCreateOutgoingDynamicStream() = 0;

 private:
  friend class test::QuicSpdySessionPeer;

  std::unique_ptr<QuicHeadersStream> headers_stream_;

  // If set, redirect all data through the headers stream in order to
  // simulate forced HOL blocking between streams as happens in
  // HTTP/2 over TCP.
  bool force_hol_blocking_;

  DISALLOW_COPY_AND_ASSIGN(QuicSpdySession);
};

}  // namespace net

#endif  // NET_QUIC_QUIC_SPDY_SESSION_H_
