// Copyright 2021 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_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
#define QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_

#include <memory>

#include "absl/base/attributes.h"
#include "absl/container/flat_hash_set.h"
#include "absl/types/optional.h"
#include "quic/core/http/quic_spdy_session.h"
#include "quic/core/http/web_transport_stream_adapter.h"
#include "quic/core/quic_error_codes.h"
#include "quic/core/quic_stream.h"
#include "quic/core/quic_types.h"
#include "quic/core/web_transport_interface.h"
#include "spdy/core/spdy_header_block.h"

namespace quic {

class QuicSpdySession;
class QuicSpdyStream;

enum class WebTransportHttp3RejectionReason {
  kNone,
  kNoStatusCode,
  kWrongStatusCode,
  kMissingDraftVersion,
  kUnsupportedDraftVersion,
};

// A session of WebTransport over HTTP/3.  The session is owned by
// QuicSpdyStream object for the CONNECT stream that established it.
//
// WebTransport over HTTP/3 specification:
// <https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3>
class QUIC_EXPORT_PRIVATE WebTransportHttp3
    : public WebTransportSession,
      public QuicSpdyStream::Http3DatagramRegistrationVisitor,
      public QuicSpdyStream::Http3DatagramVisitor {
 public:
  WebTransportHttp3(QuicSpdySession* session, QuicSpdyStream* connect_stream,
                    WebTransportSessionId id,
                    bool attempt_to_use_datagram_contexts);

  void HeadersReceived(const spdy::SpdyHeaderBlock& headers);
  void SetVisitor(std::unique_ptr<WebTransportVisitor> visitor) {
    visitor_ = std::move(visitor);
  }

  WebTransportSessionId id() { return id_; }
  bool ready() { return ready_; }
  absl::optional<QuicDatagramContextId> context_id() const {
    return context_id_;
  }

  void AssociateStream(QuicStreamId stream_id);
  void OnStreamClosed(QuicStreamId stream_id) { streams_.erase(stream_id); }
  void OnConnectStreamClosing();

  size_t NumberOfAssociatedStreams() { return streams_.size(); }

  void CloseSession(WebTransportSessionError error_code,
                    absl::string_view error_message) override;
  void OnCloseReceived(WebTransportSessionError error_code,
                       absl::string_view error_message);
  void OnConnectStreamFinReceived();

  // It is legal for WebTransport to be closed without a
  // CLOSE_WEBTRANSPORT_SESSION capsule.  We always send a capsule, but we still
  // need to ensure we handle this case correctly.
  void CloseSessionWithFinOnlyForTests();

  // 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.
  WebTransportStream* AcceptIncomingBidirectionalStream() override;
  WebTransportStream* AcceptIncomingUnidirectionalStream() override;

  bool CanOpenNextOutgoingBidirectionalStream() override;
  bool CanOpenNextOutgoingUnidirectionalStream() override;
  WebTransportStream* OpenOutgoingBidirectionalStream() override;
  WebTransportStream* OpenOutgoingUnidirectionalStream() override;

  MessageStatus SendOrQueueDatagram(QuicMemSlice datagram) override;
  QuicByteCount GetMaxDatagramSize() const override;
  void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) override;

  // From QuicSpdyStream::Http3DatagramVisitor.
  void OnHttp3Datagram(QuicStreamId stream_id,
                       absl::optional<QuicDatagramContextId> context_id,
                       absl::string_view payload) override;

  // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
  void OnContextReceived(QuicStreamId stream_id,
                         absl::optional<QuicDatagramContextId> context_id,
                         DatagramFormatType format_type,
                         absl::string_view format_additional_data) override;
  void OnContextClosed(QuicStreamId stream_id,
                       absl::optional<QuicDatagramContextId> context_id,
                       ContextCloseCode close_code,
                       absl::string_view close_details) override;

  bool close_received() const { return close_received_; }
  WebTransportHttp3RejectionReason rejection_reason() const {
    return rejection_reason_;
  }

 private:
  // Notifies the visitor that the connection has been closed.  Ensures that the
  // visitor is only ever called once.
  void MaybeNotifyClose();

  QuicSpdySession* const session_;        // Unowned.
  QuicSpdyStream* const connect_stream_;  // Unowned.
  const WebTransportSessionId id_;
  absl::optional<QuicDatagramContextId> context_id_;
  // |ready_| is set to true when the peer has seen both sets of headers.
  bool ready_ = false;
  // Whether we know which |context_id_| to use. On the client this is always
  // true, and on the server it becomes true when we receive a context
  // registration capsule.
  bool context_is_known_ = false;
  // Whether |context_id_| is currently registered with |connect_stream_|.
  bool context_currently_registered_ = false;
  std::unique_ptr<WebTransportVisitor> visitor_;
  absl::flat_hash_set<QuicStreamId> streams_;
  quiche::QuicheCircularDeque<QuicStreamId> incoming_bidirectional_streams_;
  quiche::QuicheCircularDeque<QuicStreamId> incoming_unidirectional_streams_;

  bool close_sent_ = false;
  bool close_received_ = false;
  bool close_notified_ = false;

  WebTransportHttp3RejectionReason rejection_reason_ =
      WebTransportHttp3RejectionReason::kNone;
  // Those are set to default values, which are used if the session is not
  // closed cleanly using an appropriate capsule.
  WebTransportSessionError error_code_ = 0;
  std::string error_message_ = "";
};

class QUIC_EXPORT_PRIVATE WebTransportHttp3UnidirectionalStream
    : public QuicStream {
 public:
  // Incoming stream.
  WebTransportHttp3UnidirectionalStream(PendingStream* pending,
                                        QuicSpdySession* session);
  // Outgoing stream.
  WebTransportHttp3UnidirectionalStream(QuicStreamId id,
                                        QuicSpdySession* session,
                                        WebTransportSessionId session_id);

  // Sends the stream type and the session ID on the stream.
  void WritePreamble();

  // Implementation of QuicStream.
  void OnDataAvailable() override;
  void OnCanWriteNewData() override;
  void OnClose() override;
  void OnStreamReset(const QuicRstStreamFrame& frame) override;
  bool OnStopSending(QuicResetStreamError error) override;
  void OnWriteSideInDataRecvdState() override;

  WebTransportStream* interface() { return &adapter_; }
  void SetUnblocked() { sequencer()->SetUnblocked(); }

 private:
  QuicSpdySession* session_;
  WebTransportStreamAdapter adapter_;
  absl::optional<WebTransportSessionId> session_id_;
  bool needs_to_send_preamble_;

  bool ReadSessionId();
  // Closes the stream if all of the data has been received.
  void MaybeCloseIncompleteStream();
};

// Remaps HTTP/3 error code into a WebTransport error code.  Returns nullopt if
// the provided code is outside of valid range.
QUIC_EXPORT_PRIVATE absl::optional<WebTransportStreamError>
Http3ErrorToWebTransport(uint64_t http3_error_code);

// Same as above, but returns default error value (zero) when none could be
// mapped.
QUIC_EXPORT_PRIVATE WebTransportStreamError
Http3ErrorToWebTransportOrDefault(uint64_t http3_error_code);

// Remaps WebTransport error code into an HTTP/3 error code.
QUIC_EXPORT_PRIVATE uint64_t
WebTransportErrorToHttp3(WebTransportStreamError webtransport_error_code);

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
