// Copyright (c) 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.

// This header contains interfaces that abstract away different backing
// protocols for WebTransport.

#ifndef QUICHE_WEB_TRANSPORT_WEB_TRANSPORT_H_
#define QUICHE_WEB_TRANSPORT_WEB_TRANSPORT_H_

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

// The dependencies of this API should be kept minimal and independent of
// specific transport implementations.
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/quiche_callbacks.h"
#include "quiche/common/quiche_mem_slice.h"

namespace webtransport {

enum class Perspective { kClient, kServer };

// A numeric ID uniquely identifying a WebTransport stream. Note that by design,
// those IDs are not available in the Web API, and the IDs do not necessarily
// match between client and server perspective, since there may be a proxy
// between them.
using StreamId = uint32_t;
// Application-specific error code used for resetting either the read or the
// write half of the stream.
using StreamErrorCode = uint32_t;
// Application-specific error code used for closing a WebTransport session.
using SessionErrorCode = uint32_t;

// WebTransport priority as defined in
// https://w3c.github.io/webtransport/#webtransportsendstream-write
// The rules are as follows:
// - Streams with the same priority are handled in FIFO order.
// - Streams with the same group_id but different send_order are handled
//   strictly in order.
// - Different group_ids are handled in the FIFO order.
using SendGroupId = uint32_t;
using SendOrder = int64_t;
struct QUICHE_EXPORT StreamPriority {
  SendGroupId send_group_id = 0;
  SendOrder send_order = 0;

  bool operator==(const StreamPriority& other) const {
    return send_group_id == other.send_group_id &&
           send_order == other.send_order;
  }
};

// An outcome of a datagram send call.
enum class DatagramStatusCode {
  // Datagram has been successfully sent or placed into the datagram queue.
  kSuccess,
  // Datagram has not been sent since the underlying QUIC connection is blocked
  // by the congestion control.  Note that this can only happen if the queue is
  // full.
  kBlocked,
  // Datagram has not been sent since it is too large to fit into a single
  // UDP packet.
  kTooBig,
  // An unspecified internal error.
  kInternalError,
};

// An outcome of a datagram send call, in both enum and human-readable form.
struct QUICHE_EXPORT DatagramStatus {
  explicit DatagramStatus(DatagramStatusCode code, std::string error_message)
      : code(code), error_message(std::move(error_message)) {}

  DatagramStatusCode code;
  std::string error_message;
};

enum class StreamType {
  kUnidirectional,
  kBidirectional,
};

// Based on
// https://w3c.github.io/webtransport/#dictdef-webtransportdatagramstats.
struct QUICHE_EXPORT DatagramStats {
  uint64_t expired_outgoing;
  uint64_t lost_outgoing;

  // droppedIncoming is not present, since in the C++ API, we immediately
  // deliver datagrams via callback, meaning there is no queue where things
  // would be dropped.
};

// Based on https://w3c.github.io/webtransport/#web-transport-stats
// Note that this is currently not a complete implementation of that API, as
// some of those still need to be clarified in
// https://github.com/w3c/webtransport/issues/537
struct QUICHE_EXPORT SessionStats {
  absl::Duration min_rtt;
  absl::Duration smoothed_rtt;
  absl::Duration rtt_variation;

  uint64_t application_bytes_acknowledged = 0;

  uint64_t estimated_send_rate_bps;  // In bits per second.

  DatagramStats datagram_stats;
};

// The stream visitor is an application-provided object that gets notified about
// events related to a WebTransport stream.  The visitor object is owned by the
// stream itself, meaning that if the stream is ever fully closed, the visitor
// will be garbage-collected.
class QUICHE_EXPORT StreamVisitor {
 public:
  virtual ~StreamVisitor() {}

  // Called whenever the stream has new data available to read. Unless otherwise
  // specified, QUICHE stream reads are level-triggered, which means that the
  // callback will be called repeatedly as long as there is still data in the
  // buffer.
  virtual void OnCanRead() = 0;

  // Called whenever the stream is not write-blocked and can accept new data.
  virtual void OnCanWrite() = 0;

  // Called when RESET_STREAM is received for the stream.
  virtual void OnResetStreamReceived(StreamErrorCode error) = 0;
  // Called when STOP_SENDING is received for the stream.
  virtual void OnStopSendingReceived(StreamErrorCode error) = 0;
  // Called when the write side of the stream is closed and all of the data sent
  // has been acknowledged ("Data Recvd" state of RFC 9000).  Primarily used by
  // the state machine of the Web API.
  virtual void OnWriteSideInDataRecvdState() = 0;
};

// Options for writing data into a WriteStream.
class QUICHE_EXPORT StreamWriteOptions {
 public:
  StreamWriteOptions() = default;

  // If send_fin() is set to true, the write operation also sends a FIN on the
  // stream.
  bool send_fin() const { return send_fin_; }
  void set_send_fin(bool send_fin) { send_fin_ = send_fin; }

  // If buffer_unconditionally() is set to true, the write operation will buffer
  // data even if the internal buffer limit is exceeded.
  bool buffer_unconditionally() const { return buffer_unconditionally_; }
  void set_buffer_unconditionally(bool value) {
    buffer_unconditionally_ = value;
  }

 private:
  bool send_fin_ = false;
  bool buffer_unconditionally_ = false;
};

inline constexpr StreamWriteOptions kDefaultStreamWriteOptions =
    StreamWriteOptions();

// A stream (either bidirectional or unidirectional) that is contained within a
// WebTransport session.
//
// This interface is designed around the idea that a network stream stores all
// of the received data in a sequence of contiguous buffers. Because of that,
// there are two ways to read from a stream:
//   - Read() will copy data into a user-provided buffer, reassembling it if it
//     is split across multiple buffers internally.
//   - PeekNextReadableRegion()/SkipBytes() let the caller access the underlying
//     buffers directly, potentially avoiding the copying at the cost of the
//     caller having to deal with discontinuities.
//
// The writes into a WebTransport stream are all-or-nothing.  A Stream object
// has to either accept all data written into it by returning absl::OkStatus, or
// ask the caller to try again once via OnCanWrite() by returning
// absl::UnavailableError.
class QUICHE_EXPORT Stream {
 public:
  struct QUICHE_EXPORT ReadResult {
    // Number of bytes actually read.
    size_t bytes_read = 0;
    // Whether the FIN has been received; if true, no further data will arrive
    // on the stream, and the stream object can be soon potentially garbage
    // collected.
    bool fin = false;
  };

  struct PeekResult {
    // The next available chunk in the sequencer buffer.
    absl::string_view peeked_data;
    // True if all of the data up to the FIN has been read.
    bool fin_next = false;
    // True if all of the data up to the FIN has been received (but not
    // necessarily read).
    bool all_data_received = false;

    // Indicates that `SkipBytes()` will make progress if called.
    bool has_data() const { return !peeked_data.empty() || fin_next; }
  };

  virtual ~Stream() {}

  // Reads at most `buffer.size()` bytes into `buffer`.
  [[nodiscard]] virtual ReadResult Read(absl::Span<char> buffer) = 0;

  // Reads all available data and appends it to the end of `output`.
  [[nodiscard]] virtual ReadResult Read(std::string* output) = 0;

  // Indicates the total number of bytes that can be read from the stream.
  virtual size_t ReadableBytes() const = 0;

  // Returns a contiguous buffer to read (or an empty buffer, if there is no
  // data to read). See `ProcessAllReadableRegions` below for an example of how
  // to use this method while handling FIN correctly.
  virtual PeekResult PeekNextReadableRegion() const = 0;

  // Equivalent to reading `bytes`, but does not perform any copying. `bytes`
  // must be less than or equal to `ReadableBytes()`. The return value indicates
  // if the FIN has been reached. `SkipBytes(0)` can be used to consume the FIN
  // if it's the only thing remaining on the stream.
  [[nodiscard]] virtual bool SkipBytes(size_t bytes) = 0;

  // Writes `data` into the stream.  If the write succeeds, the ownership is
  // transferred to the stream; if it does not, the behavior is undefined -- the
  // users of this API should check `CanWrite()` before calling `Writev()`.
  virtual absl::Status Writev(absl::Span<quiche::QuicheMemSlice> data,
                              const StreamWriteOptions& options) = 0;

  // Indicates whether it is possible to write into stream right now.
  virtual bool CanWrite() const = 0;

  // Legacy convenience method for writing a single string_view.  New users
  // should use quiche::SendFinOnStream instead, since this method does not
  // return useful failure information.
  [[nodiscard]] bool SendFin() {
    StreamWriteOptions options;
    options.set_send_fin(true);
    return Writev(absl::Span<quiche::QuicheMemSlice>(), options).ok();
  }

  // Legacy convenience method for writing a single string_view.  New users
  // should use quiche::WriteIntoStream instead, since this method does not
  // return useful failure information.
  [[nodiscard]] bool Write(absl::string_view data) {
    quiche::QuicheMemSlice slice = quiche::QuicheMemSlice::Copy(data);
    return Writev(absl::MakeSpan(&slice, 1), kDefaultStreamWriteOptions).ok();
  }

  // An ID that is unique within the session.  Those are not exposed to the user
  // via the web API, but can be used internally for bookkeeping and
  // diagnostics.
  virtual StreamId GetStreamId() const = 0;

  // Resets the read or the write side of the stream with the specified error
  // code.
  virtual void ResetWithUserCode(StreamErrorCode error) = 0;
  virtual void SendStopSending(StreamErrorCode error) = 0;

  // A general-purpose stream reset method that may be used when a specific
  // error code is not available.
  virtual void ResetDueToInternalError() = 0;
  // If the stream has not been already reset, reset the stream. This is
  // primarily used in the JavaScript API when the stream object has been
  // garbage collected.
  virtual void MaybeResetDueToStreamObjectGone() = 0;

  // Sets the send group and the send order of the stream as defined in
  // https://w3c.github.io/webtransport/#dictdef-webtransportsendstreamoptions
  virtual void SetPriority(const StreamPriority& priority) = 0;

  virtual StreamVisitor* visitor() = 0;
  virtual void SetVisitor(std::unique_ptr<StreamVisitor> visitor) = 0;
};

// Visitor that gets notified about events related to a WebTransport session.
class QUICHE_EXPORT SessionVisitor {
 public:
  virtual ~SessionVisitor() {}

  // Notifies the visitor when the session is ready to exchange application
  // data.
  virtual void OnSessionReady() = 0;

  // Notifies the visitor when the session has been closed.
  virtual void OnSessionClosed(SessionErrorCode error_code,
                               const std::string& error_message) = 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 OnDatagramReceived(absl::string_view datagram) = 0;

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

// An abstract interface for a WebTransport session.
//
// *** AN IMPORTANT NOTE ABOUT STREAM LIFETIMES ***
// Stream objects are managed internally by the underlying QUIC stack, and can
// go away at any time due to the peer resetting the stream. Because of that,
// any pointers to the stream objects returned by this class MUST NEVER be
// retained long-term, except inside the stream visitor (the stream visitor is
// owned by the stream object). If you need to store a reference to a stream,
// consider one of the two following options:
//   (1) store a stream ID,
//   (2) store a weak pointer to the stream visitor, and then access the stream
//       via the said visitor (the visitor is guaranteed to be alive as long as
//       the stream is alive).
class QUICHE_EXPORT Session {
 public:
  virtual ~Session() {}

  // Closes the WebTransport session in question with the specified |error_code|
  // and |error_message|.
  virtual void CloseSession(SessionErrorCode error_code,
                            absl::string_view error_message) = 0;

  // 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.  See the class note regarding the lifetime of the returned stream
  // object.
  virtual Stream* AcceptIncomingBidirectionalStream() = 0;
  virtual Stream* AcceptIncomingUnidirectionalStream() = 0;

  // Returns true if flow control allows opening a new stream.
  //
  // IMPORTANT: See the class note regarding the lifetime of the returned stream
  // object.
  virtual bool CanOpenNextOutgoingBidirectionalStream() = 0;
  virtual bool CanOpenNextOutgoingUnidirectionalStream() = 0;

  // Opens a new WebTransport stream, or returns nullptr if that is not possible
  // due to flow control.  See the class note regarding the lifetime of the
  // returned stream object.
  //
  // IMPORTANT: See the class note regarding the lifetime of the returned stream
  // object.
  virtual Stream* OpenOutgoingBidirectionalStream() = 0;
  virtual Stream* OpenOutgoingUnidirectionalStream() = 0;

  // Returns the WebTransport stream with the corresponding ID.
  //
  // IMPORTANT: See the class note regarding the lifetime of the returned stream
  // object.
  virtual Stream* GetStreamById(StreamId id) = 0;

  virtual DatagramStatus SendOrQueueDatagram(absl::string_view datagram) = 0;
  // Returns a conservative estimate of the largest datagram size that the
  // session would be able to send.
  virtual uint64_t GetMaxDatagramSize() const = 0;
  // Sets the largest duration that a datagram can spend in the queue before
  // being silently dropped.
  virtual void SetDatagramMaxTimeInQueue(absl::Duration max_time_in_queue) = 0;

  // Returns stats that generally follow the semantics of W3C WebTransport API.
  virtual DatagramStats GetDatagramStats() = 0;
  virtual SessionStats GetSessionStats() = 0;

  // Sends a DRAIN_WEBTRANSPORT_SESSION capsule or an equivalent signal to the
  // peer indicating that the session is draining.
  virtual void NotifySessionDraining() = 0;
  // Notifies that either the session itself (DRAIN_WEBTRANSPORT_SESSION
  // capsule), or the underlying connection (HTTP GOAWAY) is being drained by
  // the peer.
  virtual void SetOnDraining(quiche::SingleUseCallback<void()> callback) = 0;

  // Returns the negotiated subprotocol, or std::nullopt, if none was
  // negotiated.
  virtual std::optional<std::string> GetNegotiatedSubprotocol() const = 0;
};

}  // namespace webtransport

#endif  // QUICHE_WEB_TRANSPORT_WEB_TRANSPORT_H_
