/** @file
 *
 *  A brief file description
 *
 *  @section license License
 *
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "tscore/Diags.h"
#include "iocore/net/quic/QUICIntUtil.h"
#include "iocore/eventsystem/IOBuffer.h"
#include "proxy/http3/Http3Frame.h"
#include "proxy/http3/Http3Config.h"

#include <algorithm>

ClassAllocator<Http3Frame, false>         http3FrameAllocator("http3FrameAllocator");
ClassAllocator<Http3DataFrame, false>     http3DataFrameAllocator("http3DataFrameAllocator");
ClassAllocator<Http3HeadersFrame, false>  http3HeadersFrameAllocator("http3HeadersFrameAllocator");
ClassAllocator<Http3SettingsFrame, false> http3SettingsFrameAllocator("http3SettingsFrameAllocator");

namespace
{
// The frame type is a variable integer as defined in QUIC (RFC 9000).
constexpr int FRAME_TYPE_MAX_BYTES = 8;
constexpr int HEADER_OVERHEAD      = 10; // This should work as long as a payload length is less than 64 bits

DbgCtl dbg_ctl_http3_frame_factory{"http3_frame_factory"};

bool
is_reserved_frame_type(uint64_t type)
{
  return type >= static_cast<uint64_t>(Http3FrameType::RESERVED) &&
         (type - static_cast<uint64_t>(Http3FrameType::RESERVED)) % 0x1f == 0;
}

} // end anonymous namespace

//
// Static functions
//

int
Http3Frame::length(const uint8_t *buf, size_t buf_len, uint64_t &length)
{
  size_t length_field_length = 0;
  return QUICVariableInt::decode(length, length_field_length, buf, buf_len);
}

Http3FrameType
Http3Frame::type(const uint8_t *buf, size_t buf_len)
{
  uint64_t type              = 0;
  size_t   type_field_length = 0;
  int      ret               = QUICVariableInt::decode(type, type_field_length, buf, buf_len);
  ink_assert(ret != 1);
  if (type <= static_cast<uint64_t>(Http3FrameType::X_MAX_DEFINED)) {
    return static_cast<Http3FrameType>(type);
  } else if (is_reserved_frame_type(type)) {
    return Http3FrameType::RESERVED;
  } else {
    return Http3FrameType::UNKNOWN;
  }
}

//
// Generic Frame
//

Http3Frame::Http3Frame(IOBufferReader &reader) : _reader(&reader)
{
  // Type field and Length field are variable-length integers, which can be 64 bits for each.
  // 16 bytes (128 bits) is large enough to contain the two fields.
  constexpr int MAX_HEADER_SIZE = 16;
  uint8_t       header[MAX_HEADER_SIZE];
  uint8_t      *p          = reinterpret_cast<uint8_t *>(reader.memcpy(header, MAX_HEADER_SIZE));
  uint64_t      header_len = p - header;

  // Type
  size_t   type_field_length = 0;
  uint64_t type              = 0;
  // Ideally we'd simply pass this->_type to decode, but arm compilers complain with:
  // error: dereferencing type-punned pointer will break strict-aliasing rules
  int ret = QUICVariableInt::decode(type, type_field_length, header, header_len);
  if (ret != 0) {
    this->_is_valid = false;
    return;
  }
  this->_type = static_cast<Http3FrameType>(type);

  // Check if we can proceed to read Length field
  if (header_len <= type_field_length) {
    this->_is_valid = false;
    return;
  }

  // Length
  size_t length_field_length = 0;
  ret = QUICVariableInt::decode(this->_length, length_field_length, header + type_field_length, header_len - type_field_length);
  if (ret != 0) {
    this->_is_valid = false;
    return;
  }

  // Rest of the data is Frame Payload
  this->_reader->consume(type_field_length + length_field_length);
  this->_payload_offset = type_field_length + length_field_length;
}

Http3Frame::Http3Frame(Http3FrameType type) : _type(type) {}

Http3Frame::~Http3Frame()
{
  if (this->_reader) {
    this->_reader->dealloc();
  }
}

bool
Http3Frame::is_valid() const
{
  return this->_is_valid;
}

uint64_t
Http3Frame::total_length() const
{
  return this->_payload_offset + this->length();
}

uint64_t
Http3Frame::length() const
{
  return this->_length;
}

Http3FrameType
Http3Frame::type() const
{
  const auto type = static_cast<uint64_t>(this->_type);

  if (type <= static_cast<uint64_t>(Http3FrameType::X_MAX_DEFINED)) {
    return this->_type;
  } else if (is_reserved_frame_type(type)) {
    return Http3FrameType::RESERVED;
  } else {
    return Http3FrameType::UNKNOWN;
  }
}

bool
Http3Frame::update()
{
  if (!this->_is_ready) {
    this->_is_ready = this->_parse();
  }

  return this->_is_ready;
}

bool
Http3Frame::_parse()
{
  return true;
}

Ptr<IOBufferBlock>
Http3Frame::to_io_buffer_block() const
{
  Ptr<IOBufferBlock> block;
  return block;
}

void
Http3Frame::reset(IOBufferReader &reader)
{
  this->~Http3Frame();
  new (this) Http3Frame(reader);
}

//
// DATA Frame
//

// For receiving frame
Http3DataFrame::Http3DataFrame(IOBufferReader &reader) : Http3Frame(reader)
{
  this->_payload_len = this->_length;
}

// For sending frame
Http3DataFrame::Http3DataFrame(IOBufferReader &reader, size_t payload_len)
  : Http3Frame(Http3FrameType::DATA), _payload_len(payload_len)
{
  uint8_t    header[HEADER_OVERHEAD];
  size_t     n       = 0;
  size_t     written = 0;
  MIOBuffer *buf;

  this->_length = this->_payload_len;

  buf                = new_MIOBuffer(BUFFER_SIZE_INDEX_32K);
  this->_whole_frame = buf->alloc_reader()->get_current_block();
  QUICVariableInt::encode(header, UINT64_MAX, n, static_cast<uint64_t>(this->_type));
  written += n;
  QUICVariableInt::encode(header + written, UINT64_MAX, n, this->_length);
  written += n;

  buf->write(header, written);
  buf->write(&reader, payload_len);
  free_MIOBuffer(buf);
}

Ptr<IOBufferBlock>
Http3DataFrame::to_io_buffer_block() const
{
  return this->_whole_frame;
}

void
Http3DataFrame::reset(IOBufferReader &reader)
{
  this->~Http3DataFrame();
  new (this) Http3DataFrame(reader);
}

uint64_t
Http3DataFrame::payload_length() const
{
  return this->_length;
}

bool
Http3DataFrame::_parse()
{
  return this->_reader->read_avail() >= static_cast<int64_t>(this->_length);
}

IOBufferReader *
Http3DataFrame::data() const
{
  return _reader;
}

//
// HEADERS Frame
//
Http3HeadersFrame::Http3HeadersFrame(IOBufferReader &reader) : Http3Frame(reader) {}

Http3HeadersFrame::Http3HeadersFrame(IOBufferReader &header_block_reader, size_t header_block_len)
  : Http3Frame(Http3FrameType::HEADERS), _header_block_len(header_block_len), _header_block_reader(header_block_reader.clone())
{
  this->_length = header_block_len;
}

Http3HeadersFrame::~Http3HeadersFrame()
{
  if (this->_header_block_reader != nullptr) {
    this->_header_block_reader->dealloc();
  } else {
    ats_free(this->_header_block);
  }
}

Ptr<IOBufferBlock>
Http3HeadersFrame::to_io_buffer_block() const
{
  Ptr<IOBufferBlock> block;
  size_t             n       = 0;
  size_t             written = 0;

  block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(HEADER_OVERHEAD + this->length(), BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  QUICVariableInt::encode(block_start, UINT64_MAX, n, static_cast<uint64_t>(this->_type));
  written += n;
  QUICVariableInt::encode(block_start + written, UINT64_MAX, n, this->_length);
  written += n;
  if (this->_header_block_reader != nullptr) {
    this->_header_block_reader->memcpy(block_start + written, this->_header_block_len);
  } else {
    memcpy(block_start + written, this->_header_block, this->_header_block_len);
  }
  written += this->_header_block_len;

  block->fill(written);
  return block;
}

void
Http3HeadersFrame::reset(IOBufferReader &reader)
{
  this->~Http3HeadersFrame();
  new (this) Http3HeadersFrame(reader);
}

const uint8_t *
Http3HeadersFrame::header_block() const
{
  return this->_header_block;
}

uint64_t
Http3HeadersFrame::header_block_length() const
{
  return this->_header_block_len;
}

bool
Http3HeadersFrame::_parse()
{
  if (this->_reader->read_avail() != static_cast<int64_t>(this->_length)) {
    // Whole payload is not received yet
    return false;
  }

  this->_header_block_len = this->_length;
  this->_header_block     = static_cast<uint8_t *>(ats_malloc(this->_header_block_len));
  this->_reader->memcpy(this->_header_block, this->_header_block_len);

  return true;
}

//
// SETTINGS Frame
//

Http3SettingsFrame::Http3SettingsFrame(IOBufferReader &reader, uint32_t max_settings)
  : Http3Frame(reader), _max_settings(max_settings)
{
}

Ptr<IOBufferBlock>
Http3SettingsFrame::to_io_buffer_block() const
{
  Ptr<IOBufferBlock> header_block;
  Ptr<IOBufferBlock> payload_block;
  size_t             n       = 0;
  size_t             written = 0;

  payload_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  payload_block->alloc(iobuffer_size_to_index(Http3SettingsFrame::MAX_PAYLOAD_SIZE, BUFFER_SIZE_INDEX_32K));
  uint8_t *payload_block_start = reinterpret_cast<uint8_t *>(payload_block->start());

  for (auto &it : this->_settings) {
    QUICIntUtil::write_QUICVariableInt(static_cast<uint64_t>(it.first), payload_block_start + written, &n);
    written += n;
    QUICIntUtil::write_QUICVariableInt(it.second, payload_block_start + written, &n);
    written += n;
  }

  // Exercise the requirement that unknown identifiers be ignored. - 4.2.5.1.
  QUICIntUtil::write_QUICVariableInt(static_cast<uint64_t>(Http3SettingsId::UNKNOWN), payload_block_start + written, &n);
  written += n;
  QUICIntUtil::write_QUICVariableInt(0, payload_block_start + written, &n);
  written += n;
  payload_block->fill(written);

  size_t payload_len = written;
  written            = 0;

  header_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  header_block->alloc(iobuffer_size_to_index(HEADER_OVERHEAD, BUFFER_SIZE_INDEX_32K));
  uint8_t *header_block_start = reinterpret_cast<uint8_t *>(header_block->start());

  QUICVariableInt::encode(header_block_start, UINT64_MAX, n, static_cast<uint64_t>(this->_type));
  written += n;
  QUICVariableInt::encode(header_block_start + written, UINT64_MAX, n, payload_len);
  written += n;
  header_block->fill(written);

  header_block->next = payload_block;

  return header_block;
}

void
Http3SettingsFrame::reset(IOBufferReader &reader)
{
  this->~Http3SettingsFrame();
  new (this) Http3SettingsFrame(reader);
}

Http3ErrorUPtr
Http3SettingsFrame::get_error() const
{
  return std::make_unique<Http3Error>(Http3ErrorClass::CONNECTION, this->_error_code, this->_error_reason);
}

bool
Http3SettingsFrame::contains(Http3SettingsId id) const
{
  auto p = this->_settings.find(id);
  return (p != this->_settings.end());
}

uint64_t
Http3SettingsFrame::get(Http3SettingsId id) const
{
  auto p = this->_settings.find(id);
  if (p != this->_settings.end()) {
    return p->second;
  }

  return 0;
}

void
Http3SettingsFrame::set(Http3SettingsId id, uint64_t value)
{
  this->_settings[id] = value;
}

bool
Http3SettingsFrame::_parse()
{
  if (this->_reader->read_avail() != static_cast<int64_t>(this->_length)) {
    // Whole payload is not received yet
    return false;
  }

  uint8_t *buf = static_cast<uint8_t *>(ats_malloc(this->_length));
  this->_reader->memcpy(buf, this->_length);

  size_t   len       = 0;
  uint32_t nsettings = 0;

  while (len < this->_length) {
    if (nsettings >= this->_max_settings) {
      this->_error_code   = Http3ErrorCode::H3_EXCESSIVE_LOAD;
      this->_error_reason = reinterpret_cast<const char *>("too many settings");
      this->_is_valid     = false;
      break;
    }

    size_t id_len = QUICVariableInt::size(buf + len);
    if ((len + id_len) >=
        this->_length) { // if the id is larger than the buffer or at the boundary of the buffer (i.e. no value), it is invalid
      this->_error_code   = Http3ErrorCode::H3_SETTINGS_ERROR;
      this->_error_reason = reinterpret_cast<const char *>("invalid SETTINGS frame");
      break;
    }
    uint64_t id  = QUICIntUtil::read_QUICVariableInt(buf + len, this->_length - len);
    len         += id_len;

    size_t value_len = QUICVariableInt::size(buf + len);
    if ((len + value_len) > this->_length) {
      this->_error_code   = Http3ErrorCode::H3_SETTINGS_ERROR;
      this->_error_reason = reinterpret_cast<const char *>("invalid SETTINGS frame");
      break;
    }
    uint64_t value  = QUICIntUtil::read_QUICVariableInt(buf + len, this->_length - len);
    len            += value_len;

    // Ignore any SETTINGS identifier it does not understand.
    bool ignore = true;
    for (const auto &known_id : Http3SettingsFrame::VALID_SETTINGS_IDS) {
      if (id == static_cast<uint64_t>(known_id)) {
        ignore = false;
        break;
      }
    }

    if (ignore) {
      continue;
    }

    this->_settings.insert(std::make_pair(static_cast<Http3SettingsId>(id), value));
    ++nsettings;
  }

  if (len != this->_length) {
    // TODO: make connection error with HTTP_MALFORMED_FRAME
    this->_is_valid = false;
  }

  ats_free(buf);

  return true;
}

//
// Http3FrameFactory
//
Http3FrameUPtr
Http3FrameFactory::create_null_frame()
{
  return {nullptr, &Http3FrameDeleter::delete_null_frame};
}

Http3FrameUPtr
Http3FrameFactory::create(IOBufferReader &reader)
{
  ts::Http3Config::scoped_config params;
  Http3Frame                    *frame = nullptr;

  uint8_t           type_buf[FRAME_TYPE_MAX_BYTES]{};
  std::size_t const type_avail{std::min<std::size_t>(reader.read_avail(), sizeof(type_buf))};
  reader.memcpy(type_buf, type_avail);
  Http3FrameType type = Http3Frame::type(type_buf, type_avail);

  switch (type) {
  case Http3FrameType::HEADERS:
    frame = http3HeadersFrameAllocator.alloc();
    new (frame) Http3HeadersFrame(reader);
    return Http3FrameUPtr(frame, &Http3FrameDeleter::delete_headers_frame);
  case Http3FrameType::DATA:
    frame = http3DataFrameAllocator.alloc();
    new (frame) Http3DataFrame(reader);
    return Http3FrameUPtr(frame, &Http3FrameDeleter::delete_data_frame);
  case Http3FrameType::SETTINGS:
    frame = http3SettingsFrameAllocator.alloc();
    new (frame) Http3SettingsFrame(reader, params->max_settings());
    return Http3FrameUPtr(frame, &Http3FrameDeleter::delete_settings_frame);
  default:
    // Unknown frame
    Dbg(dbg_ctl_http3_frame_factory, "Unknown frame type %hhx", static_cast<uint8_t>(type));
    frame = http3FrameAllocator.alloc();
    new (frame) Http3Frame(reader);
    return Http3FrameUPtr(frame, &Http3FrameDeleter::delete_frame);
  }
}

std::shared_ptr<Http3Frame>
Http3FrameFactory::fast_create(IOBufferReader &reader)
{
  uint8_t           type_buf[FRAME_TYPE_MAX_BYTES]{};
  std::size_t const type_avail{std::min<std::size_t>(reader.read_avail(), sizeof(type_buf))};
  reader.memcpy(type_buf, type_avail);
  Http3FrameType type = Http3Frame::type(type_buf, type_avail);
  if (type == Http3FrameType::UNKNOWN) {
    if (!this->_unknown_frame) {
      this->_unknown_frame = Http3FrameFactory::create(reader);
    } else {
      this->_unknown_frame->reset(reader);
    }
    return this->_unknown_frame;
  }

  std::shared_ptr<Http3Frame> frame = this->_reusable_frames[static_cast<uint8_t>(type)];

  if (frame == nullptr) {
    frame = Http3FrameFactory::create(reader);
    if (frame != nullptr) {
      this->_reusable_frames[static_cast<uint8_t>(type)] = frame;
    }
  } else {
    frame->reset(reader);
  }

  return frame;
}

Http3HeadersFrameUPtr
Http3FrameFactory::create_headers_frame(IOBufferReader *header_block_reader, size_t header_block_len)
{
  Http3HeadersFrame *frame = http3HeadersFrameAllocator.alloc();
  new (frame) Http3HeadersFrame(*header_block_reader, header_block_len);
  // The frame clones the reader before this, so consuming here only advances the caller's
  // reader (for chunking header blocks larger than one generate_frame() call), not the frame's
  // own clone.
  header_block_reader->consume(header_block_len);
  return Http3HeadersFrameUPtr(frame, &Http3FrameDeleter::delete_headers_frame);
}

Http3DataFrameUPtr
Http3FrameFactory::create_data_frame(IOBufferReader *reader, size_t payload_len)
{
  Http3DataFrame *frame = http3DataFrameAllocator.alloc();
  new (frame) Http3DataFrame(*reader, payload_len);
  reader->consume(payload_len);

  return Http3DataFrameUPtr(frame, &Http3FrameDeleter::delete_data_frame);
}
