#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/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{
              static_cast<Http2SettingsId>(entry.settings_id), 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;
  }
  // Unexpected value.
  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, ToInvalidFrameError(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
