// Copyright (c) 2019 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 QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_

#include <cstdint>
#include <memory>

#include "url/gurl.h"
#include "url/origin.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
#include "net/third_party/quiche/src/quic/core/quic_config.h"
#include "net/third_party/quiche/src/quic/core/quic_connection.h"
#include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h"
#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
#include "net/third_party/quiche/src/quic/core/quic_server_id.h"
#include "net/third_party/quiche/src/quic/core/quic_session.h"
#include "net/third_party/quiche/src/quic/core/quic_stream.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_optional.h"
#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h"
#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h"
#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"

namespace quic {

// A client session for the QuicTransport protocol.
class QUIC_EXPORT_PRIVATE QuicTransportClientSession
    : public QuicSession,
      public QuicTransportSessionInterface {
 public:
  class QUIC_EXPORT_PRIVATE ClientVisitor {
   public:
    virtual ~ClientVisitor() {}

    // Notifies the visitor when the client indication has been sent and the
    // connection is ready to exchange application data.
    virtual void OnSessionReady() = 0;

    // Notifies the visitor when a new stream has been received.  The stream in
    // question can be retrieved using AcceptIncomingBidirectionalStream() or
    // AcceptIncomingUnidirectionalStream().
    virtual void OnIncomingBidirectionalStreamAvailable() = 0;
    virtual void OnIncomingUnidirectionalStreamAvailable() = 0;

    // Notifies the visitor when a new datagram has been received.
    virtual void OnIncomingDatagramAvailable() = 0;

    // Notifies the visitor that a new outgoing stream can now be created.
    virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
    virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
  };

  QuicTransportClientSession(QuicConnection* connection,
                             Visitor* owner,
                             const QuicConfig& config,
                             const ParsedQuicVersionVector& supported_versions,
                             const GURL& url,
                             QuicCryptoClientConfig* crypto_config,
                             url::Origin origin,
                             ClientVisitor* visitor);

  std::vector<std::string> GetAlpnsToOffer() const override {
    return std::vector<std::string>({QuicTransportAlpn()});
  }
  void OnAlpnSelected(quiche::QuicheStringPiece alpn) override;
  bool alpn_received() const { return alpn_received_; }

  void CryptoConnect() { crypto_stream_->CryptoConnect(); }

  bool ShouldKeepConnectionAlive() const override { return true; }

  QuicCryptoStream* GetMutableCryptoStream() override {
    return crypto_stream_.get();
  }
  const QuicCryptoStream* GetCryptoStream() const override {
    return crypto_stream_.get();
  }

  // Returns true once the encryption has been established and the client
  // indication has been sent.  No application data will be read or written
  // before the connection is ready.  Once the connection becomes ready, this
  // method will never return false.
  bool IsSessionReady() const override { return ready_; }

  QuicStream* CreateIncomingStream(QuicStreamId id) override;
  QuicStream* CreateIncomingStream(PendingStream* /*pending*/) override {
    QUIC_BUG << "QuicTransportClientSession::CreateIncomingStream("
                "PendingStream) not implemented";
    return nullptr;
  }

  void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;
  void SetDefaultEncryptionLevel(EncryptionLevel level) override;
  void OnMessageReceived(quiche::QuicheStringPiece message) override;

  // Return the earliest incoming stream that has been received by the session
  // but has not been accepted.  Returns nullptr if there are no incoming
  // streams.
  QuicTransportStream* AcceptIncomingBidirectionalStream();
  QuicTransportStream* AcceptIncomingUnidirectionalStream();

  using QuicSession::CanOpenNextOutgoingBidirectionalStream;
  using QuicSession::CanOpenNextOutgoingUnidirectionalStream;
  QuicTransportStream* OpenOutgoingBidirectionalStream();
  QuicTransportStream* OpenOutgoingUnidirectionalStream();

  using QuicSession::datagram_queue;
  QuicOptional<std::string> ReadDatagram();

 protected:
  class QUIC_EXPORT_PRIVATE ClientIndication : public QuicStream {
   public:
    using QuicStream::QuicStream;

    // This method should never be called, since the stream is client-initiated
    // unidirectional.
    void OnDataAvailable() override {
      QUIC_BUG << "Received data on a write-only stream";
    }
  };

  // Creates and activates a QuicTransportStream for the given ID.
  QuicTransportStream* CreateStream(QuicStreamId id);

  // Serializes the client indication as described in
  // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2
  std::string SerializeClientIndication();
  // Creates the client indication stream and sends the client indication on it.
  void SendClientIndication();

  void OnCanCreateNewOutgoingStream(bool unidirectional) override;

  std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
  GURL url_;
  url::Origin origin_;
  ClientVisitor* visitor_;  // not owned
  bool client_indication_sent_ = false;
  bool alpn_received_ = false;
  bool ready_ = false;

  // Contains all of the streams that has been received by the session but have
  // not been processed by the application.
  // TODO(vasilvv): currently, we always send MAX_STREAMS as long as the overall
  // maximum number of streams for the connection has not been exceeded. We
  // should also limit the maximum number of streams that the consuming code
  // has not accepted to a smaller number, by checking the size of
  // |incoming_bidirectional_streams_| and |incoming_unidirectional_streams_|
  // before sending MAX_STREAMS.
  QuicDeque<QuicTransportStream*> incoming_bidirectional_streams_;
  QuicDeque<QuicTransportStream*> incoming_unidirectional_streams_;

  // Buffer for the incoming datagrams.
  QuicDeque<std::string> incoming_datagrams_;
  // Maximum size of the |incoming_datagrams_| buffer.  Can only go up.
  size_t max_incoming_datagrams_ = 128;
};

}  // namespace quic

#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
