// Copyright (c) 2023 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_WEB_TRANSPORT_ENCAPSULATED_ENCAPSULATED_WEB_TRANSPORT_H_
#define QUICHE_WEB_TRANSPORT_ENCAPSULATED_ENCAPSULATED_WEB_TRANSPORT_H_

#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/attributes.h"
#include "absl/container/node_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "quiche/common/capsule.h"
#include "quiche/common/http/http_header_block.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/quiche_buffer_allocator.h"
#include "quiche/common/quiche_callbacks.h"
#include "quiche/common/quiche_circular_deque.h"
#include "quiche/common/quiche_stream.h"
#include "quiche/common/simple_buffer_allocator.h"
#include "quiche/web_transport/web_transport.h"
#include "quiche/web_transport/web_transport_priority_scheduler.h"

namespace webtransport {

constexpr bool IsUnidirectionalId(StreamId id) { return id & 0b10; }
constexpr bool IsBidirectionalId(StreamId id) {
  return !IsUnidirectionalId(id);
}
constexpr bool IsIdOpenedBy(StreamId id, Perspective perspective) {
  return (id & 0b01) ^ (perspective == Perspective::kClient);
}

using FatalErrorCallback = quiche::SingleUseCallback<void(absl::string_view)>;

// Implementation of the WebTransport over HTTP/2 protocol; works over any
// arbitrary bidirectional bytestream that can be prefixed with HTTP headers.
// Specification: https://datatracker.ietf.org/doc/draft-ietf-webtrans-http2/
class QUICHE_EXPORT EncapsulatedSession
    : public webtransport::Session,
      public quiche::WriteStreamVisitor,
      public quiche::ReadStreamVisitor,
      public quiche::CapsuleParser::Visitor {
 public:
  // The state machine of the transport.
  enum State {
    // The transport object has been created, but
    // InitializeClient/InitializeServer has not been called yet.
    kUninitialized,
    // The client has sent its own headers, but haven't received a response yet.
    kWaitingForHeaders,
    // Both the client and the server headers have been processed.
    kSessionOpen,
    // The session close has been requested, but the CLOSE capsule hasn't been
    // sent yet.
    kSessionClosing,
    // The session has been closed; no further data will be exchanged.
    kSessionClosed,
  };

  // The `fatal_error_callback` implies that any state related to the session
  // should be torn down after it's been called.
  EncapsulatedSession(Perspective perspective,
                      FatalErrorCallback fatal_error_callback);

  // WebTransport uses HTTP headers in a similar way to how QUIC uses SETTINGS;
  // thus, the headers are necessary to initialize the session.
  void InitializeClient(std::unique_ptr<SessionVisitor> visitor,
                        quiche::HttpHeaderBlock& outgoing_headers,
                        quiche::WriteStream* writer,
                        quiche::ReadStream* reader);
  void InitializeServer(std::unique_ptr<SessionVisitor> visitor,
                        const quiche::HttpHeaderBlock& incoming_headers,
                        quiche::HttpHeaderBlock& outgoing_headers,
                        quiche::WriteStream* writer,
                        quiche::ReadStream* reader);
  void ProcessIncomingServerHeaders(const quiche::HttpHeaderBlock& headers);

  // webtransport::Session implementation.
  void CloseSession(SessionErrorCode error_code,
                    absl::string_view error_message) override;
  Stream* AcceptIncomingBidirectionalStream() override;
  Stream* AcceptIncomingUnidirectionalStream() override;
  bool CanOpenNextOutgoingBidirectionalStream() override;
  bool CanOpenNextOutgoingUnidirectionalStream() override;
  Stream* OpenOutgoingBidirectionalStream() override;
  Stream* OpenOutgoingUnidirectionalStream() override;
  DatagramStatus SendOrQueueDatagram(absl::string_view datagram) override;
  uint64_t GetMaxDatagramSize() const override;
  void SetDatagramMaxTimeInQueue(absl::Duration max_time_in_queue) override;
  Stream* GetStreamById(StreamId id) override;
  DatagramStats GetDatagramStats() override;
  SessionStats GetSessionStats() override;
  void NotifySessionDraining() override;
  void SetOnDraining(quiche::SingleUseCallback<void()> callback) override;

  // quiche::WriteStreamVisitor implementation.
  void OnCanWrite() override;
  // quiche::ReadStreamVisitor implementation.
  void OnCanRead() override;
  // quiche::CapsuleParser::Visitor implementation.
  bool OnCapsule(const quiche::Capsule& capsule) override;
  void OnCapsuleParseFailure(absl::string_view error_message) override;

  State state() const { return state_; }

  // Cleans up the state for all of the streams that have been closed.  QUIC
  // uses timers to safely delete closed streams while minimizing the risk that
  // something on stack holds an active pointer to them; WebTransport over
  // HTTP/2 does not have any timers in it, making that approach inapplicable
  // here. This class does automatically run garbage collection at the end of
  // every OnCanRead() call (since it's a top-level entrypoint that is likely to
  // come directly from I/O handler), but if the application does not happen to
  // read data frequently, manual calls to this function may be requried.
  void GarbageCollectStreams();

 private:
  // If the amount of data buffered in the socket exceeds the amount specified
  // here, CanWrite() will start returning false.
  static constexpr size_t kDefaultMaxBufferedStreamData = 16 * 1024;

  class InnerStream : public Stream {
   public:
    InnerStream(EncapsulatedSession* session, StreamId id);
    InnerStream(const InnerStream&) = delete;
    InnerStream(InnerStream&&) = delete;
    InnerStream& operator=(const InnerStream&) = delete;
    InnerStream& operator=(InnerStream&&) = delete;

    // ReadStream implementation.
    ABSL_MUST_USE_RESULT ReadResult Read(absl::Span<char> output) override;
    ABSL_MUST_USE_RESULT ReadResult Read(std::string* output) override;
    size_t ReadableBytes() const override;
    PeekResult PeekNextReadableRegion() const override;
    bool SkipBytes(size_t bytes) override;

    // WriteStream implementation.
    absl::Status Writev(absl::Span<const absl::string_view> data,
                        const quiche::StreamWriteOptions& options) override;
    bool CanWrite() const override;

    // TerminableStream implementation.
    void AbruptlyTerminate(absl::Status error) override;

    // Stream implementation.
    StreamId GetStreamId() const override { return id_; }
    StreamVisitor* visitor() override { return visitor_.get(); }
    void SetVisitor(std::unique_ptr<StreamVisitor> visitor) override {
      visitor_ = std::move(visitor);
    }

    void ResetWithUserCode(StreamErrorCode error) override;
    void SendStopSending(StreamErrorCode error) override;

    void ResetDueToInternalError() override { ResetWithUserCode(0); }
    void MaybeResetDueToStreamObjectGone() override { ResetWithUserCode(0); }

    void SetPriority(const StreamPriority& priority) override;

    void CloseReadSide(std::optional<StreamErrorCode> error);
    void CloseWriteSide(std::optional<StreamErrorCode> error);
    bool CanBeGarbageCollected() const {
      return read_side_closed_ && write_side_closed_;
    }

    bool HasPendingWrite() const { return !pending_write_.empty(); }
    void FlushPendingWrite();

    void ProcessCapsule(const quiche::Capsule& capsule);

   private:
    // Struct for storing data that can potentially either stored inside the
    // object or inside some other object on the stack. Here is roughly how this
    // works:
    //   1. A read is enqueued with `data` pointing to a temporary buffer, and
    //      `storage` being empty.
    //   2. Visitor::OnCanRead() is called, potentially causing the user to
    //      consume the data from the temporary buffer directly.
    //   3. If user does not consume data immediately, it's copied to `storage`
    //      (and the pointer to `data` is updated) so that it can be read later.
    struct IncomingRead {
      absl::string_view data;
      std::string storage;

      size_t size() const { return data.size(); }
    };

    // Tries to send `data`; may send less if limited by flow control.
    [[nodiscard]] size_t WriteInner(absl::Span<const absl::string_view> data,
                                    bool fin);

    EncapsulatedSession* session_;
    StreamId id_;
    std::unique_ptr<StreamVisitor> visitor_;
    quiche::QuicheCircularDeque<IncomingRead> incoming_reads_;
    std::string pending_write_;
    bool read_side_closed_;
    bool write_side_closed_;
    bool reset_frame_sent_ = false;
    bool stop_sending_sent_ = false;
    bool fin_received_ = false;
    bool fin_consumed_ = false;
    bool fin_buffered_ = false;
  };

  struct BufferedClose {
    SessionErrorCode error_code = 0;
    std::string error_message;
  };

  Perspective perspective_;
  State state_ = kUninitialized;
  std::unique_ptr<SessionVisitor> visitor_ = nullptr;
  FatalErrorCallback fatal_error_callback_;
  quiche::SingleUseCallback<void()> draining_callback_;
  quiche::WriteStream* writer_ = nullptr;  // Not owned.
  quiche::ReadStream* reader_ = nullptr;   // Not owned.
  quiche::QuicheBufferAllocator* allocator_ =
      quiche::SimpleBufferAllocator::Get();
  quiche::CapsuleParser capsule_parser_;

  size_t max_stream_data_buffered_ = kDefaultMaxBufferedStreamData;

  PriorityScheduler scheduler_;
  absl::node_hash_map<StreamId, InnerStream>
      streams_;  // Streams unregister themselves with scheduler on deletion,
                 // and thus have to be above it.
  quiche::QuicheCircularDeque<StreamId> incoming_bidirectional_streams_;
  quiche::QuicheCircularDeque<StreamId> incoming_unidirectional_streams_;
  std::vector<StreamId> streams_to_garbage_collect_;
  StreamId next_outgoing_bidi_stream_;
  StreamId next_outgoing_unidi_stream_;

  bool session_close_notified_ = false;
  bool fin_sent_ = false;

  BufferedClose buffered_session_close_;
  quiche::QuicheCircularDeque<quiche::QuicheBuffer> control_capsule_queue_;

  void OpenSession();
  absl::Status SendFin(absl::string_view data);
  void OnSessionClosed(SessionErrorCode error_code,
                       const std::string& error_message);
  void OnFatalError(absl::string_view error_message);
  void OnWriteError(absl::Status error);

  bool IsOutgoing(StreamId id) { return IsIdOpenedBy(id, perspective_); }
  bool IsIncoming(StreamId id) { return !IsOutgoing(id); }

  template <typename CapsuleType>
  void SendControlCapsule(CapsuleType capsule) {
    control_capsule_queue_.push_back(quiche::SerializeCapsule(
        quiche::Capsule(std::move(capsule)), allocator_));
    OnCanWrite();
  }

  Stream* AcceptIncomingStream(quiche::QuicheCircularDeque<StreamId>& queue);
  Stream* OpenOutgoingStream(StreamId& counter);
  void ProcessStreamCapsule(const quiche::Capsule& capsule, StreamId stream_id);
};

}  // namespace webtransport

#endif  // QUICHE_WEB_TRANSPORT_ENCAPSULATED_ENCAPSULATED_WEB_TRANSPORT_H_
