#include "http2/adapter/callback_visitor.h"

#include "http2/adapter/nghttp2_util.h"
#include "third_party/nghttp2/src/lib/includes/nghttp2/nghttp2.h"
#include "common/quiche_endian.h"

// This visitor implementation needs visibility into the
// nghttp2_session_callbacks type. There's no public header, so we'll redefine
// the struct here.
struct nghttp2_session_callbacks {
  nghttp2_send_callback send_callback;
  nghttp2_recv_callback recv_callback;
  nghttp2_on_frame_recv_callback on_frame_recv_callback;
  nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback;
  nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback;
  nghttp2_before_frame_send_callback before_frame_send_callback;
  nghttp2_on_frame_send_callback on_frame_send_callback;
  nghttp2_on_frame_not_send_callback on_frame_not_send_callback;
  nghttp2_on_stream_close_callback on_stream_close_callback;
  nghttp2_on_begin_headers_callback on_begin_headers_callback;
  nghttp2_on_header_callback on_header_callback;
  nghttp2_on_header_callback2 on_header_callback2;
  nghttp2_on_invalid_header_callback on_invalid_header_callback;
  nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
  nghttp2_select_padding_callback select_padding_callback;
  nghttp2_data_source_read_length_callback read_length_callback;
  nghttp2_on_begin_frame_callback on_begin_frame_callback;
  nghttp2_send_data_callback send_data_callback;
  nghttp2_pack_extension_callback pack_extension_callback;
  nghttp2_unpack_extension_callback unpack_extension_callback;
  nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
  nghttp2_error_callback error_callback;
  nghttp2_error_callback2 error_callback2;
};

namespace http2 {
namespace adapter {

CallbackVisitor::CallbackVisitor(Perspective perspective,
                                 const nghttp2_session_callbacks& callbacks,
                                 void* user_data)
    : perspective_(perspective),
      callbacks_(MakeCallbacksPtr(nullptr)),
      user_data_(user_data) {
  nghttp2_session_callbacks* c;
  nghttp2_session_callbacks_new(&c);
  *c = callbacks;
  callbacks_ = MakeCallbacksPtr(c);
}

ssize_t CallbackVisitor::OnReadyToSend(absl::string_view serialized) {
  return callbacks_->send_callback(nullptr, ToUint8Ptr(serialized.data()),
                                   serialized.size(), 0, user_data_);
}

void CallbackVisitor::OnConnectionError() {
  QUICHE_LOG(FATAL) << "Not implemented";
}

void CallbackVisitor::OnFrameHeader(Http2StreamId stream_id,
                                    size_t length,
                                    uint8_t type,
                                    uint8_t flags) {
  // The general strategy is to clear |current_frame_| at the start of a new
  // frame, accumulate frame information from the various callback events, then
  // invoke the on_frame_recv_callback() with the accumulated frame data.
  memset(&current_frame_, 0, sizeof(current_frame_));
  current_frame_.hd.stream_id = stream_id;
  current_frame_.hd.length = length;
  current_frame_.hd.type = type;
  current_frame_.hd.flags = flags;
  callbacks_->on_begin_frame_callback(nullptr, &current_frame_.hd, user_data_);
}

void CallbackVisitor::OnSettingsStart() {}

void CallbackVisitor::OnSetting(Http2Setting setting) {
  settings_.push_back({.settings_id = setting.id, .value = setting.value});
}

void CallbackVisitor::OnSettingsEnd() {
  current_frame_.settings.niv = settings_.size();
  current_frame_.settings.iv = settings_.data();
  callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
  settings_.clear();
}

void CallbackVisitor::OnSettingsAck() {
  // ACK is part of the flags, which were set in OnFrameHeader().
  callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
}

void CallbackVisitor::OnBeginHeadersForStream(Http2StreamId stream_id) {
  auto it = GetStreamInfo(stream_id);
  if (it->second->received_headers) {
    // At least one headers frame has already been received.
    current_frame_.headers.cat = NGHTTP2_HCAT_HEADERS;
  } else {
    switch (perspective_) {
      case Perspective::kClient:
        current_frame_.headers.cat = NGHTTP2_HCAT_RESPONSE;
        break;
      case Perspective::kServer:
        current_frame_.headers.cat = NGHTTP2_HCAT_REQUEST;
        break;
    }
  }
  callbacks_->on_begin_headers_callback(nullptr, &current_frame_, user_data_);
  it->second->received_headers = true;
}

bool CallbackVisitor::OnHeaderForStream(Http2StreamId stream_id,
                                        absl::string_view name,
                                        absl::string_view value) {
  if (callbacks_->on_header_callback) {
    return 0 == callbacks_->on_header_callback(
                    nullptr, &current_frame_, ToUint8Ptr(name.data()),
                    name.size(), ToUint8Ptr(value.data()), value.size(),
                    NGHTTP2_NV_FLAG_NONE, user_data_);
  }
  return true;
}

void CallbackVisitor::OnEndHeadersForStream(Http2StreamId stream_id) {
  callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
}

void CallbackVisitor::OnBeginDataForStream(Http2StreamId stream_id,
                                           size_t payload_length) {
  // TODO(b/181586191): Interpret padding, subtract padding from
  // |remaining_data_|.
  remaining_data_ = payload_length;
  if (remaining_data_ == 0) {
    callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
  }
}

void CallbackVisitor::OnDataForStream(Http2StreamId stream_id,
                                      absl::string_view data) {
  callbacks_->on_data_chunk_recv_callback(nullptr, current_frame_.hd.flags,
                                          stream_id, ToUint8Ptr(data.data()),
                                          data.size(), user_data_);
  remaining_data_ -= data.size();
  if (remaining_data_ == 0) {
    callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
  }
}

void CallbackVisitor::OnEndStream(Http2StreamId stream_id) {}

void CallbackVisitor::OnRstStream(Http2StreamId stream_id,
                                  Http2ErrorCode error_code) {
  current_frame_.rst_stream.error_code = static_cast<uint32_t>(error_code);
  callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
}

void CallbackVisitor::OnCloseStream(Http2StreamId stream_id,
                                    Http2ErrorCode error_code) {
  callbacks_->on_stream_close_callback(
      nullptr, stream_id, static_cast<uint32_t>(error_code), user_data_);
}

void CallbackVisitor::OnPriorityForStream(Http2StreamId stream_id,
                                          Http2StreamId parent_stream_id,
                                          int weight,
                                          bool exclusive) {
  current_frame_.priority.pri_spec.stream_id = parent_stream_id;
  current_frame_.priority.pri_spec.weight = weight;
  current_frame_.priority.pri_spec.exclusive = exclusive;
  callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
}

void CallbackVisitor::OnPing(Http2PingId ping_id, bool is_ack) {
  uint64_t network_order_opaque_data =
      quiche::QuicheEndian::HostToNet64(ping_id);
  std::memcpy(current_frame_.ping.opaque_data, &network_order_opaque_data,
              sizeof(network_order_opaque_data));
  callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
}

void CallbackVisitor::OnPushPromiseForStream(Http2StreamId stream_id,
                                             Http2StreamId promised_stream_id) {
  QUICHE_LOG(FATAL) << "Not implemented";
}

void CallbackVisitor::OnGoAway(Http2StreamId last_accepted_stream_id,
                               Http2ErrorCode error_code,
                               absl::string_view opaque_data) {
  current_frame_.goaway.last_stream_id = last_accepted_stream_id;
  current_frame_.goaway.error_code = static_cast<uint32_t>(error_code);
  current_frame_.goaway.opaque_data = ToUint8Ptr(opaque_data.data());
  current_frame_.goaway.opaque_data_len = opaque_data.size();
  callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
}

void CallbackVisitor::OnWindowUpdate(Http2StreamId stream_id,
                                     int window_increment) {
  current_frame_.window_update.window_size_increment = window_increment;
  if (callbacks_->on_frame_recv_callback) {
    callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
  }
}

void CallbackVisitor::PopulateFrame(nghttp2_frame& frame, uint8_t frame_type,
                                    Http2StreamId stream_id, size_t length,
                                    uint8_t flags, uint32_t error_code,
                                    bool sent_headers) {
  frame.hd.type = frame_type;
  frame.hd.stream_id = stream_id;
  frame.hd.length = length;
  frame.hd.flags = flags;
  const FrameType frame_type_enum = static_cast<FrameType>(frame_type);
  if (frame_type_enum == FrameType::HEADERS) {
    if (sent_headers) {
      frame.headers.cat = NGHTTP2_HCAT_HEADERS;
    } else {
      switch (perspective_) {
        case Perspective::kClient:
          QUICHE_LOG(INFO) << "First headers sent by the client for stream "
                           << stream_id << "; these are request headers";
          frame.headers.cat = NGHTTP2_HCAT_REQUEST;
          break;
        case Perspective::kServer:
          QUICHE_LOG(INFO) << "First headers sent by the server for stream "
                           << stream_id << "; these are response headers";
          frame.headers.cat = NGHTTP2_HCAT_RESPONSE;
          break;
      }
    }
  } else if (frame_type_enum == FrameType::RST_STREAM) {
    frame.rst_stream.error_code = error_code;
  } else if (frame_type_enum == FrameType::GOAWAY) {
    frame.goaway.error_code = error_code;
  }
}

int CallbackVisitor::OnBeforeFrameSent(uint8_t frame_type,
                                       Http2StreamId stream_id, size_t length,
                                       uint8_t flags) {
  if (callbacks_->before_frame_send_callback) {
    QUICHE_LOG(INFO) << "OnBeforeFrameSent(type=" << int(frame_type)
                     << ", stream_id=" << stream_id << ", length=" << length
                     << ", flags=" << int(flags) << ")";
    nghttp2_frame frame;
    auto it = GetStreamInfo(stream_id);
    // The implementation of the before_frame_send_callback doesn't look at the
    // error code, so for now it's populated with 0.
    PopulateFrame(frame, frame_type, stream_id, length, flags, /*error_code=*/0,
                  it->second->before_sent_headers);
    it->second->before_sent_headers = true;
    return callbacks_->before_frame_send_callback(nullptr, &frame, user_data_);
  }
  return 0;
}

int CallbackVisitor::OnFrameSent(uint8_t frame_type, Http2StreamId stream_id,
                                 size_t length, uint8_t flags,
                                 uint32_t error_code) {
  if (callbacks_->on_frame_send_callback) {
    QUICHE_LOG(INFO) << "OnFrameSent(type=" << int(frame_type)
                     << ", stream_id=" << stream_id << ", length=" << length
                     << ", flags=" << int(flags)
                     << ", error_code=" << error_code << ")";
    nghttp2_frame frame;
    auto it = GetStreamInfo(stream_id);
    PopulateFrame(frame, frame_type, stream_id, length, flags, error_code,
                  it->second->sent_headers);
    it->second->sent_headers = true;
    return callbacks_->on_frame_send_callback(nullptr, &frame, user_data_);
  }
  return 0;
}

void CallbackVisitor::OnReadyToSendDataForStream(Http2StreamId stream_id,
                                                 char* destination_buffer,
                                                 size_t length,
                                                 ssize_t* written,
                                                 bool* end_stream) {
  QUICHE_LOG(FATAL) << "Not implemented";
}

bool CallbackVisitor::OnInvalidFrame(Http2StreamId stream_id, int error_code) {
  QUICHE_LOG(INFO) << "OnInvalidFrame(" << stream_id << ", " << error_code
                   << ")";
  QUICHE_DCHECK_EQ(stream_id, current_frame_.hd.stream_id);
  if (callbacks_->on_invalid_frame_recv_callback) {
    return 0 == callbacks_->on_invalid_frame_recv_callback(
                    nullptr, &current_frame_, error_code, user_data_);
  }
  return true;
}

void CallbackVisitor::OnReadyToSendMetadataForStream(Http2StreamId stream_id,
                                                     char* buffer,
                                                     size_t length,
                                                     ssize_t* written) {
  QUICHE_LOG(FATAL) << "Not implemented";
}

void CallbackVisitor::OnBeginMetadataForStream(Http2StreamId stream_id,
                                               size_t payload_length) {
  QUICHE_VLOG(1) << "OnBeginMetadataForStream(stream_id=" << stream_id
                 << ", payload_length=" << payload_length << ")";
}

void CallbackVisitor::OnMetadataForStream(Http2StreamId stream_id,
                                          absl::string_view metadata) {
  QUICHE_VLOG(1) << "OnMetadataForStream(stream_id=" << stream_id
                 << ", len=" << metadata.size() << ")";
  if (callbacks_->on_extension_chunk_recv_callback) {
    int result = callbacks_->on_extension_chunk_recv_callback(
        nullptr, &current_frame_.hd, ToUint8Ptr(metadata.data()),
        metadata.size(), user_data_);
    QUICHE_DCHECK_EQ(0, result);
  }
}

bool CallbackVisitor::OnMetadataEndForStream(Http2StreamId stream_id) {
  QUICHE_LOG_IF(DFATAL, current_frame_.hd.flags != kMetadataEndFlag);
  QUICHE_VLOG(1) << "OnMetadataEndForStream(stream_id=" << stream_id << ")";
  if (callbacks_->unpack_extension_callback) {
    void* payload;
    int result = callbacks_->unpack_extension_callback(
        nullptr, &payload, &current_frame_.hd, user_data_);
    if (callbacks_->on_frame_recv_callback) {
      current_frame_.ext.payload = payload;
      callbacks_->on_frame_recv_callback(nullptr, &current_frame_, user_data_);
    }
    return (result == 0);
  }
  return true;
}

void CallbackVisitor::OnErrorDebug(absl::string_view message) {
  if (callbacks_->error_callback2) {
    callbacks_->error_callback2(nullptr, -1, message.data(), message.size(),
                                user_data_);
  }
}

CallbackVisitor::StreamInfoMap::iterator CallbackVisitor::GetStreamInfo(
    Http2StreamId stream_id) {
  auto it = stream_map_.find(stream_id);
  if (it == stream_map_.end()) {
    auto p = stream_map_.insert({stream_id, absl::make_unique<StreamInfo>()});
    it = p.first;
  }
  return it;
}

}  // namespace adapter
}  // namespace http2
