#include "quiche/http2/adapter/nghttp2_adapter.h"

#include "absl/algorithm/container.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "quiche/http2/adapter/http2_visitor_interface.h"
#include "quiche/http2/adapter/nghttp2.h"
#include "quiche/http2/adapter/nghttp2_callbacks.h"
#include "quiche/http2/adapter/nghttp2_data_provider.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_endian.h"

namespace http2 {
namespace adapter {

namespace {

using ConnectionError = Http2VisitorInterface::ConnectionError;

// A metadata source that deletes itself upon completion.
class SelfDeletingMetadataSource : public MetadataSource {
 public:
  explicit SelfDeletingMetadataSource(std::unique_ptr<MetadataSource> source)
      : source_(std::move(source)) {}

  size_t NumFrames(size_t max_frame_size) const override {
    return source_->NumFrames(max_frame_size);
  }

  std::pair<int64_t, bool> Pack(uint8_t* dest, size_t dest_len) override {
    const auto result = source_->Pack(dest, dest_len);
    if (result.first < 0 || result.second) {
      delete this;
    }
    return result;
  }

  void OnFailure() override {
    source_->OnFailure();
    delete this;
  }

 private:
  std::unique_ptr<MetadataSource> source_;
};

}  // anonymous namespace

/* static */
std::unique_ptr<NgHttp2Adapter> NgHttp2Adapter::CreateClientAdapter(
    Http2VisitorInterface& visitor, const nghttp2_option* options) {
  auto adapter = new NgHttp2Adapter(visitor, Perspective::kClient, options);
  adapter->Initialize();
  return absl::WrapUnique(adapter);
}

/* static */
std::unique_ptr<NgHttp2Adapter> NgHttp2Adapter::CreateServerAdapter(
    Http2VisitorInterface& visitor, const nghttp2_option* options) {
  auto adapter = new NgHttp2Adapter(visitor, Perspective::kServer, options);
  adapter->Initialize();
  return absl::WrapUnique(adapter);
}

bool NgHttp2Adapter::IsServerSession() const {
  int result = nghttp2_session_check_server_session(session_->raw_ptr());
  QUICHE_DCHECK_EQ(perspective_ == Perspective::kServer, result > 0);
  return result > 0;
}

int64_t NgHttp2Adapter::ProcessBytes(absl::string_view bytes) {
  const int64_t processed_bytes = session_->ProcessBytes(bytes);
  if (processed_bytes < 0) {
    visitor_.OnConnectionError(ConnectionError::kParseError);
  }
  return processed_bytes;
}

void NgHttp2Adapter::SubmitSettings(absl::Span<const Http2Setting> settings) {
  // Submit SETTINGS, converting each Http2Setting to an nghttp2_settings_entry.
  std::vector<nghttp2_settings_entry> nghttp2_settings;
  absl::c_transform(settings, std::back_inserter(nghttp2_settings),
                    [](const Http2Setting& setting) {
                      return nghttp2_settings_entry{setting.id, setting.value};
                    });
  nghttp2_submit_settings(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
                          nghttp2_settings.data(), nghttp2_settings.size());
}

void NgHttp2Adapter::SubmitPriorityForStream(Http2StreamId stream_id,
                                             Http2StreamId parent_stream_id,
                                             int weight, bool exclusive) {
  nghttp2_priority_spec priority_spec;
  nghttp2_priority_spec_init(&priority_spec, parent_stream_id, weight,
                             static_cast<int>(exclusive));
  nghttp2_submit_priority(session_->raw_ptr(), NGHTTP2_FLAG_NONE, stream_id,
                          &priority_spec);
}

void NgHttp2Adapter::SubmitPing(Http2PingId ping_id) {
  uint8_t opaque_data[8] = {};
  Http2PingId ping_id_to_serialize = quiche::QuicheEndian::HostToNet64(ping_id);
  std::memcpy(opaque_data, &ping_id_to_serialize, sizeof(Http2PingId));
  nghttp2_submit_ping(session_->raw_ptr(), NGHTTP2_FLAG_NONE, opaque_data);
}

void NgHttp2Adapter::SubmitShutdownNotice() {
  nghttp2_submit_shutdown_notice(session_->raw_ptr());
}

void NgHttp2Adapter::SubmitGoAway(Http2StreamId last_accepted_stream_id,
                                  Http2ErrorCode error_code,
                                  absl::string_view opaque_data) {
  nghttp2_submit_goaway(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
                        last_accepted_stream_id,
                        static_cast<uint32_t>(error_code),
                        ToUint8Ptr(opaque_data.data()), opaque_data.size());
}

void NgHttp2Adapter::SubmitWindowUpdate(Http2StreamId stream_id,
                                        int window_increment) {
  nghttp2_submit_window_update(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
                               stream_id, window_increment);
}

void NgHttp2Adapter::SubmitMetadata(Http2StreamId stream_id,
                                    size_t max_frame_size,
                                    std::unique_ptr<MetadataSource> source) {
  auto* wrapped_source = new SelfDeletingMetadataSource(std::move(source));
  const size_t num_frames = wrapped_source->NumFrames(max_frame_size);
  size_t num_successes = 0;
  for (size_t i = 1; i <= num_frames; ++i) {
    const int result = nghttp2_submit_extension(
        session_->raw_ptr(), kMetadataFrameType,
        i == num_frames ? kMetadataEndFlag : 0, stream_id, wrapped_source);
    if (result != 0) {
      QUICHE_LOG(DFATAL) << "Failed to submit extension frame " << i << " of "
                         << num_frames;
      break;
    }
    ++num_successes;
  }
  if (num_successes == 0) {
    delete wrapped_source;
  }
}

int NgHttp2Adapter::Send() {
  const int result = nghttp2_session_send(session_->raw_ptr());
  if (result != 0) {
    QUICHE_VLOG(1) << "nghttp2_session_send returned " << result;
    visitor_.OnConnectionError(ConnectionError::kSendError);
  }
  return result;
}

int NgHttp2Adapter::GetSendWindowSize() const {
  return session_->GetRemoteWindowSize();
}

int NgHttp2Adapter::GetStreamSendWindowSize(Http2StreamId stream_id) const {
  return nghttp2_session_get_stream_remote_window_size(session_->raw_ptr(),
                                                       stream_id);
}

int NgHttp2Adapter::GetStreamReceiveWindowLimit(Http2StreamId stream_id) const {
  return nghttp2_session_get_stream_effective_local_window_size(
      session_->raw_ptr(), stream_id);
}

int NgHttp2Adapter::GetStreamReceiveWindowSize(Http2StreamId stream_id) const {
  return nghttp2_session_get_stream_local_window_size(session_->raw_ptr(),
                                                      stream_id);
}

int NgHttp2Adapter::GetReceiveWindowSize() const {
  return nghttp2_session_get_local_window_size(session_->raw_ptr());
}

int NgHttp2Adapter::GetHpackEncoderDynamicTableSize() const {
  return nghttp2_session_get_hd_deflate_dynamic_table_size(session_->raw_ptr());
}

int NgHttp2Adapter::GetHpackDecoderDynamicTableSize() const {
  return nghttp2_session_get_hd_inflate_dynamic_table_size(session_->raw_ptr());
}

Http2StreamId NgHttp2Adapter::GetHighestReceivedStreamId() const {
  return nghttp2_session_get_last_proc_stream_id(session_->raw_ptr());
}

void NgHttp2Adapter::MarkDataConsumedForStream(Http2StreamId stream_id,
                                               size_t num_bytes) {
  int rc = session_->Consume(stream_id, num_bytes);
  if (rc != 0) {
    QUICHE_LOG(ERROR) << "Error " << rc << " marking " << num_bytes
                      << " bytes consumed for stream " << stream_id;
  }
}

void NgHttp2Adapter::SubmitRst(Http2StreamId stream_id,
                               Http2ErrorCode error_code) {
  int status =
      nghttp2_submit_rst_stream(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
                                stream_id, static_cast<uint32_t>(error_code));
  if (status < 0) {
    QUICHE_LOG(WARNING) << "Reset stream failed: " << stream_id
                        << " with status code " << status;
  }
}

int32_t NgHttp2Adapter::SubmitRequest(
    absl::Span<const Header> headers,
    std::unique_ptr<DataFrameSource> data_source, void* stream_user_data) {
  auto nvs = GetNghttp2Nvs(headers);
  std::unique_ptr<nghttp2_data_provider> provider =
      MakeDataProvider(data_source.get());

  int32_t stream_id =
      nghttp2_submit_request(session_->raw_ptr(), nullptr, nvs.data(),
                             nvs.size(), provider.get(), stream_user_data);
  sources_.emplace(stream_id, std::move(data_source));
  QUICHE_VLOG(1) << "Submitted request with " << nvs.size()
                 << " request headers and user data " << stream_user_data
                 << "; resulted in stream " << stream_id;
  return stream_id;
}

int NgHttp2Adapter::SubmitResponse(
    Http2StreamId stream_id, absl::Span<const Header> headers,
    std::unique_ptr<DataFrameSource> data_source) {
  auto nvs = GetNghttp2Nvs(headers);
  std::unique_ptr<nghttp2_data_provider> provider =
      MakeDataProvider(data_source.get());

  sources_.emplace(stream_id, std::move(data_source));

  int result = nghttp2_submit_response(session_->raw_ptr(), stream_id,
                                       nvs.data(), nvs.size(), provider.get());
  QUICHE_VLOG(1) << "Submitted response with " << nvs.size()
                 << " response headers; result = " << result;
  return result;
}

int NgHttp2Adapter::SubmitTrailer(Http2StreamId stream_id,
                                  absl::Span<const Header> trailers) {
  auto nvs = GetNghttp2Nvs(trailers);
  int result = nghttp2_submit_trailer(session_->raw_ptr(), stream_id,
                                      nvs.data(), nvs.size());
  QUICHE_VLOG(1) << "Submitted trailers with " << nvs.size()
                 << " response trailers; result = " << result;
  return result;
}

void NgHttp2Adapter::SetStreamUserData(Http2StreamId stream_id,
                                       void* stream_user_data) {
  nghttp2_session_set_stream_user_data(session_->raw_ptr(), stream_id,
                                       stream_user_data);
}

void* NgHttp2Adapter::GetStreamUserData(Http2StreamId stream_id) {
  return nghttp2_session_get_stream_user_data(session_->raw_ptr(), stream_id);
}

bool NgHttp2Adapter::ResumeStream(Http2StreamId stream_id) {
  return 0 == nghttp2_session_resume_data(session_->raw_ptr(), stream_id);
}

void NgHttp2Adapter::RemoveStream(Http2StreamId stream_id) {
  sources_.erase(stream_id);
}

NgHttp2Adapter::NgHttp2Adapter(Http2VisitorInterface& visitor,
                               Perspective perspective,
                               const nghttp2_option* options)
    : Http2Adapter(visitor),
      visitor_(visitor),
      options_(options),
      perspective_(perspective) {}

NgHttp2Adapter::~NgHttp2Adapter() {}

void NgHttp2Adapter::Initialize() {
  nghttp2_option* owned_options = nullptr;
  if (options_ == nullptr) {
    nghttp2_option_new(&owned_options);
    // Set some common options for compatibility.
    nghttp2_option_set_no_closed_streams(owned_options, 1);
    nghttp2_option_set_no_auto_window_update(owned_options, 1);
    nghttp2_option_set_max_send_header_block_length(owned_options, 0x2000000);
    nghttp2_option_set_max_outbound_ack(owned_options, 10000);
    nghttp2_option_set_user_recv_extension_type(owned_options,
                                                kMetadataFrameType);
    options_ = owned_options;
  }

  session_ = absl::make_unique<NgHttp2Session>(perspective_,
                                               callbacks::Create(), options_,
                                               static_cast<void*>(&visitor_));
  if (owned_options != nullptr) {
    nghttp2_option_del(owned_options);
  }
  options_ = nullptr;
}

}  // namespace adapter
}  // namespace http2
