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

#include "quiche/quic/masque/masque_h2_connection.h"

#include <algorithm>
#include <atomic>
#include <cerrno>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <memory>
#include <ostream>
#include <string>
#include <utility>
#include <vector>

#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "quiche/http2/adapter/http2_protocol.h"
#include "quiche/http2/adapter/http2_util.h"
#include "quiche/http2/adapter/http2_visitor_interface.h"
#include "quiche/http2/adapter/oghttp2_adapter.h"
#include "openssl/base.h"
#include "openssl/err.h"
#include "openssl/ssl.h"
#include "quiche/common/http/http_header_block.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_text_utils.h"

#define ENDPOINT info_ << ": "

using http2::adapter::Header;
using http2::adapter::Http2KnownSettingsId;

namespace quic {

namespace {

int AppendErrorToString(const char* msg, size_t msg_len, void* ctx) {
  std::string* result = reinterpret_cast<std::string*>(ctx);
  absl::StrAppend(result, "\n", absl::string_view(msg, msg_len));
  return 1;
}

absl::Status SslErrorStatus(const char* msg, int ssl_err, int ret) {
  return absl::FailedPreconditionError(FormatSslError(msg, ssl_err, ret));
}

}  // namespace

std::string FormatSslError(const char* msg, int ssl_err, int ret) {
  std::string result = absl::StrCat(msg, ": ");
  switch (ssl_err) {
    case SSL_ERROR_SSL:
      absl::StrAppend(&result, ERR_reason_error_string(ERR_peek_error()));
      break;
    case SSL_ERROR_SYSCALL:
      if (ret == 0) {
        absl::StrAppend(&result, "peer closed connection");
      } else {
        absl::StrAppend(&result, strerror(errno));
      }
      break;
    case SSL_ERROR_ZERO_RETURN:
      absl::StrAppend(&result, "received close_notify");
      break;
    default:
      absl::StrAppend(&result,
                      "unexpected error: ", SSL_error_description(ssl_err));
      break;
  }
  ERR_print_errors_cb(AppendErrorToString, &result);
  return result;
}

// static
uint32_t MasqueH2Connection::GetNextConnectionId() {
  static std::atomic<uint32_t> next_connection_id = 1;
  return next_connection_id.fetch_add(1, std::memory_order_relaxed);
}

MasqueH2Connection::MasqueH2Connection(SSL* ssl, bool is_server,
                                       Visitor* visitor,
                                       absl::string_view info_string)
    : ssl_(ssl),
      is_server_(is_server),
      info_(absl::StrCat(info_string, "-", is_server ? "S" : "C",
                         GetNextConnectionId())),
      visitor_(visitor) {}

void MasqueH2Connection::OnTransportReadable() {
  while (TryRead()) {
  }
}

MasqueH2Connection::~MasqueH2Connection() {}

void MasqueH2Connection::Abort(absl::Status error) {
  QUICHE_CHECK(!error.ok());
  if (has_closed_gracefully_) {
    QUICHE_LOG(INFO)
        << ENDPOINT
        << "Connection already closed gracefully, ignoring new error: "
        << error.message();
    return;
  }
  if (aborted()) {
    QUICHE_LOG(ERROR) << ENDPOINT
                      << "Connection already aborted, ignoring new error: "
                      << error.message();
    return;
  }
  error_ = error;
  QUICHE_LOG(ERROR) << ENDPOINT << "Aborting connection: " << error_.message();
  visitor_->OnConnectionFinished(this, error_);
}

void MasqueH2Connection::StartH2() {
  QUICHE_LOG(INFO) << ENDPOINT << "Starting H2";
  http2::adapter::OgHttp2Adapter::Options options;
  std::vector<Http2Setting> settings;
  if (is_server_) {
    options.perspective = http2::adapter::Perspective::kServer;
    settings.push_back(
        Http2Setting{Http2KnownSettingsId::ENABLE_CONNECT_PROTOCOL, 1});
  } else {
    options.perspective = http2::adapter::Perspective::kClient;
  }
  settings.push_back(
      Http2Setting{Http2KnownSettingsId::HEADER_TABLE_SIZE, 4096});
  settings.push_back(Http2Setting{Http2KnownSettingsId::ENABLE_PUSH, 0});
  settings.push_back(
      Http2Setting{Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 100});
  settings.push_back(
      Http2Setting{Http2KnownSettingsId::INITIAL_WINDOW_SIZE, 268435456});
  settings.push_back(Http2Setting{Http2KnownSettingsId::MAX_FRAME_SIZE, 16384});
  settings.push_back(
      Http2Setting{Http2KnownSettingsId::MAX_HEADER_LIST_SIZE, 65535});
  h2_adapter_ = http2::adapter::OgHttp2Adapter::Create(*this, options);
  h2_adapter_->SubmitSettings(settings);
  // Increase connection-level flow control window to 256MB.
  h2_adapter_->SubmitWindowUpdate(0, 268435456);
  visitor_->OnConnectionReady(this);
}
bool MasqueH2Connection::TryRead() {
  if (!tls_connected_) {
    int ssl_handshake_ret = SSL_do_handshake(ssl_);
    if (ssl_handshake_ret == 1) {
      tls_connected_ = true;
      StartH2();
      AttemptToSend();
    } else {
      int ssl_err = SSL_get_error(ssl_, ssl_handshake_ret);
      if (ssl_err == SSL_ERROR_WANT_READ) {
        QUICHE_DVLOG(1) << ENDPOINT
                        << "SSL_do_handshake will require another read";
        return false;
      }
      Abort(SslErrorStatus("Error while connecting to TLS", ssl_err,
                           ssl_handshake_ret));
      return false;
    }
  }
  uint8_t buffer[kBioBufferSize] = {};
  int ssl_read_ret = SSL_read(ssl_, buffer, sizeof(buffer) - 1);
  if (ssl_read_ret < 0) {
    int ssl_err = SSL_get_error(ssl_, ssl_read_ret);
    if (ssl_err == SSL_ERROR_WANT_READ) {
      return false;
    }
    Abort(
        SslErrorStatus("Error while reading from TLS", ssl_err, ssl_read_ret));
    return false;
  }
  if (ssl_read_ret == 0) {
    Abort(absl::AbortedError("TLS read closed"));
    return false;
  }
  QUICHE_DVLOG(1) << ENDPOINT << "Read " << ssl_read_ret << " bytes from TLS";
  QUICHE_DVLOG(2) << ENDPOINT << "Read TLS bytes:" << std::endl
                  << quiche::QuicheTextUtils::HexDump(absl::string_view(
                         reinterpret_cast<const char*>(buffer), ssl_read_ret));
  h2_adapter_->ProcessBytes(
      absl::string_view(reinterpret_cast<const char*>(buffer), ssl_read_ret));
  return AttemptToSend();
}

bool MasqueH2Connection::WriteDataToTls(absl::string_view data) {
  QUICHE_DVLOG(2) << ENDPOINT << "Writing " << data.size()
                  << " app bytes to TLS:" << std::endl
                  << quiche::QuicheTextUtils::HexDump(data);
  const bool buffered = !tls_write_buffer_.empty();
  const char* buffer_to_write;
  size_t size_to_write;
  if (buffered) {
    absl::StrAppend(&tls_write_buffer_, data);
    buffer_to_write = tls_write_buffer_.data();
    size_to_write = tls_write_buffer_.size();
  } else {
    buffer_to_write = data.data();
    size_to_write = data.size();
  }
  const int ssl_write_ret = SSL_write(ssl_, buffer_to_write, size_to_write);
  if (ssl_write_ret <= 0) {
    int ssl_err = SSL_get_error(ssl_, ssl_write_ret);
    if (ssl_err == SSL_ERROR_WANT_WRITE) {
      if (!buffered) {
        tls_write_buffer_ = std::string(data);
      }
      QUICHE_DVLOG(1) << ENDPOINT << "SSL_write will require another write, "
                      << "buffered " << tls_write_buffer_.size() << " bytes";
      return true;
    }
    Abort(SslErrorStatus("Error while writing data to TLS", ssl_err,
                         ssl_write_ret));
    return false;
  }
  if (ssl_write_ret == static_cast<int>(size_to_write)) {
    QUICHE_DVLOG(1) << ENDPOINT << "Wrote " << size_to_write << " bytes to TLS";
    if (buffered) {
      tls_write_buffer_.clear();
    }
  } else {
    QUICHE_DVLOG(1) << ENDPOINT << "Wrote " << ssl_write_ret << " / "
                    << size_to_write << " bytes to TLS and buffered the rest";
    if (buffered) {
      tls_write_buffer_.erase(0, ssl_write_ret);
    } else {
      tls_write_buffer_ = std::string(data.substr(ssl_write_ret));
    }
  }
  return true;
}

int64_t MasqueH2Connection::OnReadyToSend(absl::string_view serialized) {
  QUICHE_DVLOG(1) << ENDPOINT << "Writing " << serialized.size()
                  << " bytes of h2 data to TLS";
  if (!WriteDataToTls(serialized)) {
    return kSendError;
  }
  return serialized.size();
}

MasqueH2Connection::DataFrameHeaderInfo
MasqueH2Connection::OnReadyToSendDataForStream(Http2StreamId stream_id,
                                               size_t max_length) {
  MasqueH2Stream* stream = GetOrCreateH2Stream(stream_id);
  DataFrameHeaderInfo info;
  if (max_length < stream->body_to_send.size()) {
    info.payload_length = max_length;
    info.end_data = false;
  } else {
    info.payload_length = stream->body_to_send.size();
    info.end_data = stream->end_stream_pending;
  }
  info.end_stream = info.end_data;
  return info;
}

bool MasqueH2Connection::SendDataFrame(Http2StreamId stream_id,
                                       absl::string_view frame_header,
                                       size_t payload_bytes) {
  if (!WriteDataToTls(frame_header)) {
    return false;
  }
  MasqueH2Stream* stream = GetOrCreateH2Stream(stream_id);
  size_t length_to_write = std::min(payload_bytes, stream->body_to_send.size());
  if (!WriteDataToTls(stream->body_to_send.substr(0, length_to_write))) {
    return false;
  }
  if (length_to_write == stream->body_to_send.size()) {
    stream->body_to_send.clear();
  } else {
    // Remove the written bytes from the start of `body_to_send`.
    stream->body_to_send = stream->body_to_send.substr(length_to_write);
  }
  return true;
}

void MasqueH2Connection::OnConnectionError(ConnectionError error) {
  Abort(absl::AbortedError(absl::StrCat(
      "OnConnectionError: ", http2::adapter::ConnectionErrorToString(error))));
}

void MasqueH2Connection::OnSettingsStart() {}

void MasqueH2Connection::OnSetting(Http2Setting setting) {
  QUICHE_LOG(INFO) << ENDPOINT << "Received "
                   << http2::adapter::Http2SettingsIdToString(setting.id)
                   << " = " << setting.value;
}

void MasqueH2Connection::OnSettingsEnd() {}
void MasqueH2Connection::OnSettingsAck() {}

bool MasqueH2Connection::OnBeginHeadersForStream(Http2StreamId stream_id) {
  QUICHE_DVLOG(1) << ENDPOINT << "OnBeginHeadersForStream " << stream_id;
  return true;
}

MasqueH2Connection::OnHeaderResult MasqueH2Connection::OnHeaderForStream(
    Http2StreamId stream_id, absl::string_view key, absl::string_view value) {
  QUICHE_DVLOG(2) << ENDPOINT << "Stream " << stream_id << " received header "
                  << key << " = " << value;
  GetOrCreateH2Stream(stream_id)->received_headers.AppendValueOrAddHeader(
      key, value);
  return OnHeaderResult::HEADER_OK;
}

bool MasqueH2Connection::AttemptToSend() {
  if (!tls_write_buffer_.empty()) {
    QUICHE_DVLOG(1) << ENDPOINT << "Attempting to write "
                    << tls_write_buffer_.size() << " buffered bytes to TLS";
    if (!WriteDataToTls("")) {
      return false;
    }
  }
  if (!h2_adapter_) {
    return false;
  }
  int h2_send_result = h2_adapter_->Send();
  if (h2_send_result != 0) {
    Abort(absl::AbortedError("h2 adapter failed to send"));
    return false;
  }
  return true;
}

bool MasqueH2Connection::OnEndHeadersForStream(Http2StreamId stream_id) {
  MasqueH2Stream* stream = GetOrCreateH2Stream(stream_id);
  QUICHE_LOG(INFO) << ENDPOINT << "OnEndHeadersForStream " << stream_id
                   << " headers: " << stream->received_headers.DebugString();
  if (stream->response_is_streamed) {
    visitor_->OnResponse(this, stream_id, stream->received_headers,
                         /*body=*/"", /*end_stream=*/false);
  }
  return true;
}

void MasqueH2Connection::SendResponse(int32_t stream_id,
                                      const quiche::HttpHeaderBlock& headers,
                                      const std::string& body) {
  MasqueH2Stream* stream = GetOrCreateH2Stream(stream_id);
  std::vector<Header> h2_headers = ConvertHeaders(headers);
  stream->body_to_send = body;
  if (h2_adapter_->SubmitResponse(
          stream_id, h2_headers,
          /*end_stream=*/stream->body_to_send.empty()) != 0) {
    Abort(absl::InternalError(
        absl::StrCat("Failed to submit response for stream ", stream_id,
                     " with body of length ", body.size(),
                     ", headers: ", headers.DebugString())));
  }
  QUICHE_LOG(INFO) << ENDPOINT << "Sending response on stream ID " << stream_id
                   << " with body of length " << body.size()
                   << ", headers: " << headers.DebugString();
  if (!body.empty()) {
    QUICHE_DVLOG(2) << ENDPOINT << "Body to be sent:" << std::endl
                    << quiche::QuicheTextUtils::HexDump(body);
  }
}

int32_t MasqueH2Connection::SendRequest(const quiche::HttpHeaderBlock& headers,
                                        const std::string& body,
                                        bool end_stream, bool stream_response) {
  if (is_server_) {
    QUICHE_LOG(FATAL) << ENDPOINT << "Server cannot send requests";
  }
  if (!h2_adapter_) {
    QUICHE_LOG(ERROR) << ENDPOINT
                      << "Connection is not ready to send requests yet";
    return -1;
  }
  std::vector<Header> h2_headers = ConvertHeaders(headers);
  int32_t stream_id = h2_adapter_->SubmitRequest(
      h2_headers, /*end_stream=*/end_stream && body.empty(),
      /*user_data=*/nullptr);
  if (stream_id < 0) {
    Abort(absl::InvalidArgumentError(
        absl::StrCat("Failed to submit request with body of length ",
                     body.size(), ", headers: ", headers.DebugString())));
    return -1;
  }
  if (stream_id > highest_stream_id_) {
    highest_stream_id_ = stream_id;
  }
  QUICHE_LOG(INFO) << ENDPOINT << "Sending request on stream ID " << stream_id
                   << " with body of length " << body.size()
                   << ", headers: " << headers.DebugString();
  if (!body.empty()) {
    QUICHE_DVLOG(2) << ENDPOINT << "Body to be sent:" << std::endl
                    << quiche::QuicheTextUtils::HexDump(body);
  }
  MasqueH2Stream* stream = GetOrCreateH2Stream(stream_id);
  stream->response_is_streamed = stream_response;
  stream->body_to_send = body;
  stream->end_stream_pending = end_stream;
  if (!body.empty() || !end_stream) {
    h2_adapter_->ResumeStream(stream_id);
  }
  return stream_id;
}

void MasqueH2Connection::SendBodyChunk(int32_t stream_id,
                                       const std::string& body,
                                       bool end_stream) {
  QUICHE_LOG(INFO) << ENDPOINT << "SendBodyChunk stream_id: " << stream_id
                   << " body length: " << body.size()
                   << " end_stream: " << end_stream;
  QUICHE_LOG(INFO) << ENDPOINT << "SendBodyChunk Connection window: "
                   << h2_adapter_->GetSendWindowSize() << ", Stream window: "
                   << h2_adapter_->GetStreamSendWindowSize(stream_id);
  MasqueH2Stream* stream = GetOrCreateH2Stream(stream_id);
  if (stream->end_stream_pending) {
    QUICHE_LOG(DFATAL) << ENDPOINT
                       << "SendBodyChunk called when end_stream already "
                          "pending for stream "
                       << stream_id;
    return;
  }
  stream->body_to_send.append(body);
  stream->end_stream_pending = end_stream;
  h2_adapter_->ResumeStream(stream_id);
  QUICHE_LOG(INFO) << ENDPOINT << "Sending body on stream ID " << stream_id
                   << " with body of length " << body.size()
                   << ", end_stream: " << end_stream;
  AttemptToSend();
}

std::vector<Header> MasqueH2Connection::ConvertHeaders(
    const quiche::HttpHeaderBlock& headers) {
  std::vector<Header> h2_headers;
  for (const auto& [key, value] : headers) {
    h2_headers.push_back({http2::adapter::HeaderRep(std::string(key)),
                          http2::adapter::HeaderRep(std::string(value))});
  }
  return h2_headers;
}

bool MasqueH2Connection::OnBeginDataForStream(Http2StreamId stream_id,
                                              size_t payload_length) {
  QUICHE_DVLOG(1) << ENDPOINT << "OnBeginDataForStream " << stream_id
                  << " payload_length: " << payload_length;
  return true;
}

bool MasqueH2Connection::OnDataPaddingLength(Http2StreamId stream_id,
                                             size_t padding_length) {
  QUICHE_DVLOG(1) << ENDPOINT << "OnDataPaddingLength stream_id: " << stream_id
                  << " padding_length: " << padding_length;
  return true;
}

bool MasqueH2Connection::OnDataForStream(Http2StreamId stream_id,
                                         absl::string_view data) {
  MasqueH2Stream* stream = GetOrCreateH2Stream(stream_id);
  if (!stream->response_is_streamed) {
    stream->received_body.append(data);
  }
  QUICHE_LOG(INFO) << ENDPOINT << "OnDataForStream " << stream_id
                   << " new data length: " << data.size()
                   << " total length: " << stream->received_body.size();
  if (stream->response_is_streamed) {
    visitor_->OnDataForStream(this, stream_id, data, /*end_stream=*/false);
  }
  return true;
}

bool MasqueH2Connection::OnEndStream(Http2StreamId stream_id) {
  MasqueH2Stream* stream = GetOrCreateH2Stream(stream_id);
  QUICHE_LOG(INFO) << ENDPOINT << "Received END_STREAM for stream " << stream_id
                   << " body length: " << stream->received_body.size();
  QUICHE_DVLOG(2) << ENDPOINT << "Body: " << std::endl
                  << quiche::QuicheTextUtils::HexDump(stream->received_body);
  if (!stream->callback_fired) {
    stream->callback_fired = true;
    if (is_server_) {
      visitor_->OnRequest(this, stream_id, stream->received_headers,
                          stream->received_body);
    } else {
      if (stream->response_is_streamed) {
        visitor_->OnDataForStream(this, stream_id, /*data=*/"",
                                  /*end_stream=*/true);
      } else {
        visitor_->OnResponse(this, stream_id, stream->received_headers,
                             stream->received_body, /*end_stream=*/true);
      }
    }
  }
  return true;
}

void MasqueH2Connection::OnRstStream(Http2StreamId stream_id,
                                     Http2ErrorCode error_code) {
  QUICHE_LOG(INFO) << ENDPOINT << "Stream " << stream_id
                   << " reset with error code "
                   << Http2ErrorCodeToString(error_code);
  auto it = h2_streams_.find(stream_id);
  if (it != h2_streams_.end()) {
    if (!it->second->callback_fired) {
      it->second->callback_fired = true;
      visitor_->OnStreamFailure(
          this, stream_id,
          absl::InvalidArgumentError(
              absl::StrCat("Stream ", stream_id, " reset with error code ",
                           Http2ErrorCodeToString(error_code))));
    }
  }
}

bool MasqueH2Connection::OnCloseStream(Http2StreamId stream_id,
                                       Http2ErrorCode error_code) {
  QUICHE_LOG(INFO) << ENDPOINT << "Stream " << stream_id
                   << " closed with error code "
                   << Http2ErrorCodeToString(error_code);
  auto it = h2_streams_.find(stream_id);
  if (it != h2_streams_.end()) {
    if (!it->second->callback_fired) {
      visitor_->OnStreamFailure(
          this, stream_id,
          absl::InternalError(
              absl::StrCat("Stream ", stream_id, " closed with error code ",
                           Http2ErrorCodeToString(error_code))));
    }
    h2_streams_.erase(it);
  }
  return true;
}

void MasqueH2Connection::OnPriorityForStream(Http2StreamId stream_id,
                                             Http2StreamId parent_stream_id,
                                             int weight, bool exclusive) {
  QUICHE_LOG(INFO) << ENDPOINT << "Stream " << stream_id
                   << " received priority " << weight
                   << (exclusive ? " exclusive" : "") << " parent "
                   << parent_stream_id;
}

void MasqueH2Connection::OnPing(Http2PingId ping_id, bool is_ack) {
  QUICHE_LOG(INFO) << ENDPOINT << "Received ping " << ping_id
                   << (is_ack ? " ack" : "");
}

void MasqueH2Connection::OnPushPromiseForStream(
    Http2StreamId stream_id, Http2StreamId promised_stream_id) {
  QUICHE_LOG(INFO) << ENDPOINT << "Stream " << stream_id
                   << " received push promise for stream "
                   << promised_stream_id;
}

bool MasqueH2Connection::OnGoAway(Http2StreamId last_accepted_stream_id,
                                  Http2ErrorCode error_code,
                                  absl::string_view opaque_data) {
  QUICHE_LOG(INFO) << ENDPOINT
                   << "Received GOAWAY frame with last_accepted_stream_id: "
                   << last_accepted_stream_id
                   << " error_code: " << Http2ErrorCodeToString(error_code)
                   << " opaque_data length: " << opaque_data.size();
  if (last_accepted_stream_id <= highest_stream_id_) {
    draining_ = true;
  }
  for (auto it = h2_streams_.begin(); it != h2_streams_.end();) {
    if (it->first > last_accepted_stream_id) {
      if (!it->second->callback_fired) {
        visitor_->OnStreamFailure(
            this, it->first,
            absl::InternalError(
                absl::StrCat("Stream ", it->first,
                             " cancelled due to GOAWAY with error code ",
                             Http2ErrorCodeToString(error_code))));
      }
      h2_streams_.erase(it++);
    } else {
      ++it;
    }
  }
  if (h2_streams_.empty() && !has_closed_gracefully_) {
    QUICHE_LOG(INFO) << ENDPOINT
                     << "Received GOAWAY and all streams closed, closing "
                        "connection gracefully";
    has_closed_gracefully_ = true;
    visitor_->OnConnectionFinished(this, absl::OkStatus());
  }
  return true;
}

void MasqueH2Connection::OnWindowUpdate(Http2StreamId stream_id,
                                        int window_increment) {
  QUICHE_LOG(INFO) << ENDPOINT << "Stream " << stream_id
                   << " received window update " << window_increment;
}

int MasqueH2Connection::OnBeforeFrameSent(uint8_t frame_type,
                                          Http2StreamId stream_id,
                                          size_t length, uint8_t flags) {
  QUICHE_DVLOG(1) << ENDPOINT << "OnBeforeFrameSent frame_type: "
                  << static_cast<int>(frame_type) << " stream_id: " << stream_id
                  << " length: " << length
                  << " flags: " << static_cast<int>(flags);
  return 0;
}

int MasqueH2Connection::OnFrameSent(uint8_t frame_type, Http2StreamId stream_id,
                                    size_t length, uint8_t flags,
                                    uint32_t error_code) {
  QUICHE_DVLOG(1) << ENDPOINT
                  << "OnFrameSent frame_type: " << static_cast<int>(frame_type)
                  << " stream_id: " << stream_id << " length: " << length
                  << " flags: " << static_cast<int>(flags)
                  << " error_code: " << error_code;
  return 0;
}

bool MasqueH2Connection::OnInvalidFrame(Http2StreamId stream_id,
                                        InvalidFrameError error) {
  QUICHE_LOG(INFO) << ENDPOINT << "Stream " << stream_id
                   << " received invalid frame error "
                   << http2::adapter::InvalidFrameErrorToString(error);
  return true;
}

void MasqueH2Connection::OnBeginMetadataForStream(Http2StreamId stream_id,
                                                  size_t payload_length) {
  QUICHE_LOG(INFO) << ENDPOINT << "Stream " << stream_id
                   << " about to receive metadata of length " << payload_length;
}

bool MasqueH2Connection::OnMetadataForStream(Http2StreamId stream_id,
                                             absl::string_view metadata) {
  QUICHE_LOG(INFO) << ENDPOINT << "Stream " << stream_id
                   << " received metadata of length " << metadata.size();
  return true;
}

bool MasqueH2Connection::OnMetadataEndForStream(Http2StreamId stream_id) {
  QUICHE_LOG(INFO) << ENDPOINT << "Stream " << stream_id
                   << " done receiving metadata";
  return true;
}

void MasqueH2Connection::OnErrorDebug(absl::string_view message) {
  QUICHE_LOG(ERROR) << ENDPOINT << "OnErrorDebug: " << message;
}

MasqueH2Connection::MasqueH2Stream* MasqueH2Connection::GetOrCreateH2Stream(
    Http2StreamId stream_id) {
  auto it = h2_streams_.find(stream_id);
  if (it != h2_streams_.end()) {
    return it->second.get();
  }
  return h2_streams_.insert({stream_id, std::make_unique<MasqueH2Stream>()})
      .first->second.get();
}

}  // namespace quic

#undef ENDPOINT
