// 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 (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;
  }
  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();
  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
