#include "http2/adapter/nghttp2_callbacks.h"

#include <cstdint>
#include <cstring>

#include "absl/strings/string_view.h"
#include "http2/adapter/data_source.h"
#include "http2/adapter/http2_protocol.h"
#include "http2/adapter/http2_visitor_interface.h"
#include "http2/adapter/nghttp2_data_provider.h"
#include "http2/adapter/nghttp2_util.h"
#include "third_party/nghttp2/nghttp2.h"
#include "third_party/nghttp2/src/lib/includes/nghttp2/nghttp2.h"
#include "common/platform/api/quiche_bug_tracker.h"
#include "common/platform/api/quiche_logging.h"
#include "common/quiche_endian.h"

namespace http2 {
namespace adapter {
namespace callbacks {

ssize_t OnReadyToSend(nghttp2_session* /* session */, const uint8_t* data,
                      size_t length, int flags, void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  const int64_t result = visitor->OnReadyToSend(ToStringView(data, length));
  QUICHE_VLOG(1) << "OnReadyToSend(length=" << length << ", flags=" << flags
                 << ") returning " << result;
  if (result > 0) {
    return result;
  } else if (result == Http2VisitorInterface::kSendBlocked) {
    return -504;  // NGHTTP2_ERR_WOULDBLOCK
  } else {
    return -902;  // NGHTTP2_ERR_CALLBACK_FAILURE
  }
}

int OnBeginFrame(nghttp2_session* /* session */,
                 const nghttp2_frame_hd* header,
                 void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  bool result = visitor->OnFrameHeader(header->stream_id, header->length,
                                       header->type, header->flags);
  if (!result) {
    return NGHTTP2_ERR_CALLBACK_FAILURE;
  }
  if (header->type == NGHTTP2_DATA) {
    result = visitor->OnBeginDataForStream(header->stream_id, header->length);
  } else if (header->type == kMetadataFrameType) {
    visitor->OnBeginMetadataForStream(header->stream_id, header->length);
  }
  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
}

int OnFrameReceived(nghttp2_session* /* session */,
                    const nghttp2_frame* frame,
                    void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  const Http2StreamId stream_id = frame->hd.stream_id;
  switch (frame->hd.type) {
    // The beginning of the DATA frame is handled in OnBeginFrame(), and the
    // beginning of the header block is handled in client/server-specific
    // callbacks. This callback handles the point at which the entire logical
    // frame has been received and processed.
    case NGHTTP2_DATA:
      if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
        visitor->OnEndStream(stream_id);
      }
      break;
    case NGHTTP2_HEADERS: {
      if (frame->hd.flags & NGHTTP2_FLAG_END_HEADERS) {
        const bool result = visitor->OnEndHeadersForStream(stream_id);
        if (!result) {
          return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
      }
      if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
        visitor->OnEndStream(stream_id);
      }
      break;
    }
    case NGHTTP2_PRIORITY: {
      nghttp2_priority_spec priority_spec = frame->priority.pri_spec;
      visitor->OnPriorityForStream(stream_id, priority_spec.stream_id,
                                   priority_spec.weight,
                                   priority_spec.exclusive != 0);
      break;
    }
    case NGHTTP2_RST_STREAM: {
      visitor->OnRstStream(stream_id,
                           ToHttp2ErrorCode(frame->rst_stream.error_code));
      break;
    }
    case NGHTTP2_SETTINGS:
      if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
        visitor->OnSettingsAck();
      } else {
        visitor->OnSettingsStart();
        for (size_t i = 0; i < frame->settings.niv; ++i) {
          nghttp2_settings_entry entry = frame->settings.iv[i];
          // The nghttp2_settings_entry uses int32_t for the ID; we must cast.
          visitor->OnSetting(Http2Setting{
              .id = static_cast<Http2SettingsId>(entry.settings_id),
              .value = entry.value});
        }
        visitor->OnSettingsEnd();
      }
      break;
    case NGHTTP2_PUSH_PROMISE:
      // This case is handled by headers-related callbacks:
      //   1. visitor->OnPushPromiseForStream() is invoked in the client-side
      //      OnHeadersStart() adapter callback, as nghttp2 only allows clients
      //      to receive PUSH_PROMISE frames.
      //   2. visitor->OnHeaderForStream() is invoked for each server push
      //      request header in the PUSH_PROMISE header block.
      //   3. This switch statement is reached once all server push request
      //      headers have been parsed.
      break;
    case NGHTTP2_PING: {
      Http2PingId ping_id;
      std::memcpy(&ping_id, frame->ping.opaque_data, sizeof(Http2PingId));
      visitor->OnPing(quiche::QuicheEndian::NetToHost64(ping_id),
                      (frame->hd.flags & NGHTTP2_FLAG_ACK) != 0);
      break;
    }
    case NGHTTP2_GOAWAY: {
      absl::string_view opaque_data(
          reinterpret_cast<const char*>(frame->goaway.opaque_data),
          frame->goaway.opaque_data_len);
      const bool result = visitor->OnGoAway(
          frame->goaway.last_stream_id,
          ToHttp2ErrorCode(frame->goaway.error_code), opaque_data);
      if (!result) {
        return NGHTTP2_ERR_CALLBACK_FAILURE;
      }
      break;
    }
    case NGHTTP2_WINDOW_UPDATE: {
      visitor->OnWindowUpdate(stream_id,
                              frame->window_update.window_size_increment);
      break;
    }
    case NGHTTP2_CONTINUATION:
      // This frame type should not be passed to any callbacks, according to
      // https://nghttp2.org/documentation/enums.html#c.NGHTTP2_CONTINUATION.
      QUICHE_LOG(ERROR) << "Unexpected receipt of NGHTTP2_CONTINUATION type!";
      break;
    case NGHTTP2_ALTSVC:
      break;
    case NGHTTP2_ORIGIN:
      break;
  }

  return 0;
}

int OnBeginHeaders(nghttp2_session* /* session */,
                   const nghttp2_frame* frame,
                   void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  const bool result = visitor->OnBeginHeadersForStream(frame->hd.stream_id);
  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
}

int OnHeader(nghttp2_session* /* session */, const nghttp2_frame* frame,
             nghttp2_rcbuf* name, nghttp2_rcbuf* value, uint8_t /*flags*/,
             void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  const Http2VisitorInterface::OnHeaderResult result =
      visitor->OnHeaderForStream(frame->hd.stream_id, ToStringView(name),
                                 ToStringView(value));
  switch (result) {
    case Http2VisitorInterface::HEADER_OK:
      return 0;
    case Http2VisitorInterface::HEADER_CONNECTION_ERROR:
      return NGHTTP2_ERR_CALLBACK_FAILURE;
    case Http2VisitorInterface::HEADER_RST_STREAM:
      return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
  }
}

int OnBeforeFrameSent(nghttp2_session* /* session */,
                      const nghttp2_frame* frame, void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  LogBeforeSend(*frame);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  return visitor->OnBeforeFrameSent(frame->hd.type, frame->hd.stream_id,
                                    frame->hd.length, frame->hd.flags);
}

int OnFrameSent(nghttp2_session* /* session */, const nghttp2_frame* frame,
                void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  uint32_t error_code = 0;
  if (frame->hd.type == NGHTTP2_RST_STREAM) {
    error_code = frame->rst_stream.error_code;
  } else if (frame->hd.type == NGHTTP2_GOAWAY) {
    error_code = frame->goaway.error_code;
  }
  return visitor->OnFrameSent(frame->hd.type, frame->hd.stream_id,
                              frame->hd.length, frame->hd.flags, error_code);
}

int OnInvalidFrameReceived(nghttp2_session* /* session */,
                           const nghttp2_frame* frame, int lib_error_code,
                           void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  const bool result =
      visitor->OnInvalidFrame(frame->hd.stream_id, lib_error_code);
  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
}

int OnDataChunk(nghttp2_session* /* session */, uint8_t /*flags*/,
                Http2StreamId stream_id, const uint8_t* data, size_t len,
                void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  const bool result = visitor->OnDataForStream(
      stream_id, absl::string_view(reinterpret_cast<const char*>(data), len));
  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
}

int OnStreamClosed(nghttp2_session* /* session */,
                   Http2StreamId stream_id,
                   uint32_t error_code,
                   void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  visitor->OnCloseStream(stream_id, ToHttp2ErrorCode(error_code));
  return 0;
}

int OnExtensionChunkReceived(nghttp2_session* /*session*/,
                             const nghttp2_frame_hd* hd, const uint8_t* data,
                             size_t len, void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  if (hd->type != kMetadataFrameType) {
    QUICHE_LOG(ERROR) << "Unexpected frame type: "
                      << static_cast<int>(hd->type);
    return NGHTTP2_ERR_CANCEL;
  }
  const bool result =
      visitor->OnMetadataForStream(hd->stream_id, ToStringView(data, len));
  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
}

int OnUnpackExtensionCallback(nghttp2_session* /*session*/, void** /*payload*/,
                              const nghttp2_frame_hd* hd, void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  if (hd->flags == kMetadataEndFlag) {
    const bool result = visitor->OnMetadataEndForStream(hd->stream_id);
    if (!result) {
      return NGHTTP2_ERR_CALLBACK_FAILURE;
    }
  }
  return 0;
}

ssize_t OnPackExtensionCallback(nghttp2_session* /*session*/, uint8_t* buf,
                                size_t len, const nghttp2_frame* frame,
                                void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* source = static_cast<MetadataSource*>(frame->ext.payload);
  if (source == nullptr) {
    QUICHE_BUG(payload_is_nullptr) << "Extension frame payload for stream "
                                   << frame->hd.stream_id << " is null!";
    return NGHTTP2_ERR_CALLBACK_FAILURE;
  }
  const std::pair<int64_t, bool> result = source->Pack(buf, len);
  if (result.first < 0) {
    return NGHTTP2_ERR_CALLBACK_FAILURE;
  }
  const bool end_metadata_flag = (frame->hd.flags & kMetadataEndFlag);
  QUICHE_LOG_IF(DFATAL, result.second != end_metadata_flag)
      << "Metadata ends: " << result.second
      << " has kMetadataEndFlag: " << end_metadata_flag;
  return result.first;
}

int OnError(nghttp2_session* /*session*/, int /*lib_error_code*/,
            const char* msg, size_t len, void* user_data) {
  QUICHE_CHECK_NE(user_data, nullptr);
  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
  visitor->OnErrorDebug(absl::string_view(msg, len));
  return 0;
}

nghttp2_session_callbacks_unique_ptr Create() {
  nghttp2_session_callbacks* callbacks;
  nghttp2_session_callbacks_new(&callbacks);

  nghttp2_session_callbacks_set_send_callback(callbacks, &OnReadyToSend);
  nghttp2_session_callbacks_set_on_begin_frame_callback(callbacks,
                                                        &OnBeginFrame);
  nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
                                                       &OnFrameReceived);
  nghttp2_session_callbacks_set_on_begin_headers_callback(callbacks,
                                                          &OnBeginHeaders);
  nghttp2_session_callbacks_set_on_header_callback2(callbacks, &OnHeader);
  nghttp2_session_callbacks_set_on_data_chunk_recv_callback(callbacks,
                                                            &OnDataChunk);
  nghttp2_session_callbacks_set_on_stream_close_callback(callbacks,
                                                         &OnStreamClosed);
  nghttp2_session_callbacks_set_before_frame_send_callback(callbacks,
                                                           &OnBeforeFrameSent);
  nghttp2_session_callbacks_set_on_frame_send_callback(callbacks, &OnFrameSent);
  nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
      callbacks, &OnInvalidFrameReceived);
  nghttp2_session_callbacks_set_error_callback2(callbacks, &OnError);
  // on_frame_not_send_callback <- just ignored
  nghttp2_session_callbacks_set_send_data_callback(
      callbacks, &DataFrameSourceSendCallback);
  nghttp2_session_callbacks_set_pack_extension_callback(
      callbacks, &OnPackExtensionCallback);
  nghttp2_session_callbacks_set_unpack_extension_callback(
      callbacks, &OnUnpackExtensionCallback);
  nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
      callbacks, &OnExtensionChunkReceived);
  return MakeCallbacksPtr(callbacks);
}

}  // namespace callbacks
}  // namespace adapter
}  // namespace http2
