// 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.

// A toy server specific QuicSession subclass.

#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_

#include <stdint.h>

#include <list>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "net/third_party/quiche/src/quic/core/http/quic_server_session_base.h"
#include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h"
#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h"
#include "net/third_party/quiche/src/quic/core/quic_packets.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
#include "net/third_party/quiche/src/quic/tools/quic_backend_response.h"
#include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h"
#include "net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h"

namespace quic {

namespace test {
class QuicSimpleServerSessionPeer;
}  // namespace test

class QuicSimpleServerSession : public QuicServerSessionBase {
 public:
  // A PromisedStreamInfo is an element of the queue to store promised
  // stream which hasn't been created yet. It keeps a mapping between promised
  // stream id with its priority and the headers sent out in PUSH_PROMISE.
  struct PromisedStreamInfo {
   public:
    PromisedStreamInfo(spdy::SpdyHeaderBlock request_headers,
                       QuicStreamId stream_id,
                       spdy::SpdyPriority priority)
        : request_headers(std::move(request_headers)),
          stream_id(stream_id),
          priority(priority),
          is_cancelled(false) {}
    spdy::SpdyHeaderBlock request_headers;
    QuicStreamId stream_id;
    spdy::SpdyPriority priority;
    bool is_cancelled;
  };

  // Takes ownership of |connection|.
  QuicSimpleServerSession(const QuicConfig& config,
                          const ParsedQuicVersionVector& supported_versions,
                          QuicConnection* connection,
                          QuicSession::Visitor* visitor,
                          QuicCryptoServerStream::Helper* helper,
                          const QuicCryptoServerConfig* crypto_config,
                          QuicCompressedCertsCache* compressed_certs_cache,
                          QuicSimpleServerBackend* quic_simple_server_backend);
  QuicSimpleServerSession(const QuicSimpleServerSession&) = delete;
  QuicSimpleServerSession& operator=(const QuicSimpleServerSession&) = delete;

  ~QuicSimpleServerSession() override;

  // Override base class to detact client sending data on server push stream.
  void OnStreamFrame(const QuicStreamFrame& frame) override;

  // Send out PUSH_PROMISE for all |resources| promised stream id in each frame
  // will increase by 2 for each item in |resources|.
  // And enqueue HEADERS block in those PUSH_PROMISED for sending push response
  // later.
  virtual void PromisePushResources(
      const std::string& request_url,
      const std::list<QuicBackendResponse::ServerPushInfo>& resources,
      QuicStreamId original_stream_id,
      const spdy::SpdyHeaderBlock& original_request_headers);

  void OnCanCreateNewOutgoingStream() override;

 protected:
  // QuicSession methods:
  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
  QuicSpdyStream* CreateIncomingStream(PendingStream pending) override;
  QuicSimpleServerStream* CreateOutgoingBidirectionalStream() override;
  QuicSimpleServerStream* CreateOutgoingUnidirectionalStream() override;
  // Override to return true for locally preserved server push stream.
  void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id) override;
  // Override to handle reseting locally preserved streams.
  void HandleRstOnValidNonexistentStream(
      const QuicRstStreamFrame& frame) override;

  // QuicServerSessionBaseMethod:
  QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
      const QuicCryptoServerConfig* crypto_config,
      QuicCompressedCertsCache* compressed_certs_cache) override;

  QuicSimpleServerBackend* server_backend() {
    return quic_simple_server_backend_;
  }

 private:
  friend class test::QuicSimpleServerSessionPeer;

  // Create a server push headers block by copying request's headers block.
  // But replace or add these pseudo-headers as they are specific to each
  // request:
  // :authority, :path, :method, :scheme, referer.
  // Copying the rest headers ensures they are the same as the original
  // request, especially cookies.
  spdy::SpdyHeaderBlock SynthesizePushRequestHeaders(
      std::string request_url,
      QuicBackendResponse::ServerPushInfo resource,
      const spdy::SpdyHeaderBlock& original_request_headers);

  // Send PUSH_PROMISE frame on headers stream.
  void SendPushPromise(QuicStreamId original_stream_id,
                       QuicStreamId promised_stream_id,
                       spdy::SpdyHeaderBlock headers);

  // Fetch response from cache for request headers enqueued into
  // promised_headers_and_streams_ and send them on dedicated stream until
  // reaches max_open_stream_ limit.
  // Called when return value of GetNumOpenOutgoingStreams() changes:
  //    CloseStreamInner();
  //    StreamDraining();
  // Note that updateFlowControlOnFinalReceivedByteOffset() won't change the
  // return value becasue all push streams are impossible to become locally
  // closed. Since a locally preserved stream becomes remotely closed after
  // HandlePromisedPushRequests() starts to process it, and if it is reset
  // locally afterwards, it will be immediately become closed and never get into
  // locally_closed_stream_highest_offset_. So all the streams in this map
  // are not outgoing streams.
  void HandlePromisedPushRequests();

  // Keep track of the highest stream id which has been sent in PUSH_PROMISE.
  QuicStreamId highest_promised_stream_id_;

  // Promised streams which hasn't been created yet because of max_open_stream_
  // limit. New element is added to the end of the queue.
  // Since outgoing stream is created in sequence, stream_id of each element in
  // the queue also increases by 2 from previous one's. The front element's
  // stream_id is always next_outgoing_stream_id_, and the last one is always
  // highest_promised_stream_id_.
  QuicDeque<PromisedStreamInfo> promised_streams_;

  QuicSimpleServerBackend* quic_simple_server_backend_;  // Not owned.
};

}  // namespace quic

#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
