/** @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 "QUICIncomingFrameBuffer.h"

//
// QUICIncomingFrameBuffer
//

QUICIncomingFrameBuffer::~QUICIncomingFrameBuffer()
{
  this->clear();
}

void
QUICIncomingFrameBuffer::clear()
{
  for (auto ite : this->_out_of_order_queue) {
    delete ite.second;
  }
  this->_out_of_order_queue.clear();

  while (!this->_recv_buffer.empty()) {
    delete this->_recv_buffer.front();
    this->_recv_buffer.pop();
  }

  this->_recv_offset = 0;
}

bool
QUICIncomingFrameBuffer::empty()
{
  return this->_out_of_order_queue.empty() && this->_recv_buffer.empty();
}

//
// QUICIncomingStreamFrameBuffer
//
QUICIncomingStreamFrameBuffer::~QUICIncomingStreamFrameBuffer()
{
  this->clear();
}

const QUICFrame *
QUICIncomingStreamFrameBuffer::pop()
{
  if (this->_recv_buffer.empty()) {
    auto elem = this->_out_of_order_queue.find(this->_recv_offset);
    while (elem != this->_out_of_order_queue.end()) {
      const QUICStreamFrame *frame = static_cast<const QUICStreamFrame *>(elem->second);

      this->_recv_buffer.push(frame);
      this->_recv_offset += frame->data_length();
      this->_out_of_order_queue.erase(elem);
      elem = this->_out_of_order_queue.find(this->_recv_offset);
    }
  }

  if (!this->_recv_buffer.empty()) {
    auto frame = this->_recv_buffer.front();
    this->_recv_buffer.pop();
    return frame;
  }
  return nullptr;
}

QUICConnectionErrorUPtr
QUICIncomingStreamFrameBuffer::insert(const QUICFrame *frame)
{
  const QUICStreamFrame *stream_frame = static_cast<const QUICStreamFrame *>(frame);

  QUICOffset offset = stream_frame->offset();
  size_t len        = stream_frame->data_length();

  QUICConnectionErrorUPtr err = this->_check_and_set_fin_flag(offset, len, stream_frame->has_fin_flag());
  if (err != nullptr) {
    delete frame;
    return err;
  }

  // Ignore empty stream frame except pure fin stream frame
  if (len == 0 && !stream_frame->has_fin_flag()) {
    delete frame;
    return nullptr;
  }

  if (this->_recv_offset > offset) {
    // dup frame;
    delete frame;
    return nullptr;
  } else if (this->_recv_offset == offset) {
    this->_recv_offset = offset + len;
    this->_recv_buffer.push(stream_frame);
  } else {
    auto result = this->_out_of_order_queue.insert(std::make_pair(offset, stream_frame));
    if (!result.second) {
      // Duplicate frame doesn't need to be inserted
      delete stream_frame;
    }
  }

  return nullptr;
}

void
QUICIncomingStreamFrameBuffer::clear()
{
  this->_fin_offset = UINT64_MAX;
  this->_max_offset = 0;

  super::clear();
}

QUICConnectionErrorUPtr
QUICIncomingStreamFrameBuffer::_check_and_set_fin_flag(QUICOffset offset, size_t len, bool fin_flag)
{
  // stream with fin flag {11.3. Stream Final Offset}
  // Once a final offset for a stream is known, it cannot change.
  // If a RESET_STREAM or STREAM frame causes the final offset to change for a stream,
  // an endpoint SHOULD respond with a FINAL_SIZE_ERROR error (see Section 12).
  // A receiver SHOULD treat receipt of data at or beyond the final offset as a
  // FINAL_SIZE_ERROR error, even after a stream is closed.

  // {11.3. Stream Final Offset}
  // A receiver SHOULD treat receipt of data at or beyond the final offset as a
  // FINAL_SIZE_ERROR error, even after a stream is closed.
  if (fin_flag) {
    if (this->_fin_offset != UINT64_MAX) {
      if (this->_fin_offset == offset + len) {
        // dup fin frame
        return nullptr;
      }
      return std::make_unique<QUICConnectionError>(QUICTransErrorCode::FINAL_SIZE_ERROR);
    }

    this->_fin_offset = offset + len;

    if (this->_max_offset > this->_fin_offset) {
      return std::make_unique<QUICConnectionError>(QUICTransErrorCode::FINAL_SIZE_ERROR);
    }

  } else if (this->_fin_offset != UINT64_MAX && this->_fin_offset <= offset) {
    return std::make_unique<QUICConnectionError>(QUICTransErrorCode::FINAL_SIZE_ERROR);
  }
  this->_max_offset = std::max(offset + len, this->_max_offset);

  return nullptr;
}

bool
QUICIncomingStreamFrameBuffer::is_transfer_goal_set() const
{
  return this->_fin_offset != UINT64_MAX;
}

uint64_t
QUICIncomingStreamFrameBuffer::transfer_progress() const
{
  return this->_max_offset;
}

uint64_t
QUICIncomingStreamFrameBuffer::transfer_goal() const
{
  return this->_fin_offset;
}

bool
QUICIncomingStreamFrameBuffer::is_cancelled() const
{
  return false;
}

//
// QUICIncomingCryptoFrameBuffer
//
QUICIncomingCryptoFrameBuffer::~QUICIncomingCryptoFrameBuffer()
{
  super::clear();
}

const QUICFrame *
QUICIncomingCryptoFrameBuffer::pop()
{
  if (this->_recv_buffer.empty()) {
    auto elem = this->_out_of_order_queue.find(this->_recv_offset);
    while (elem != this->_out_of_order_queue.end()) {
      const QUICCryptoFrame *frame = static_cast<const QUICCryptoFrame *>(elem->second);

      this->_recv_buffer.push(frame);
      this->_recv_offset += frame->data_length();
      this->_out_of_order_queue.erase(elem);
      elem = this->_out_of_order_queue.find(this->_recv_offset);
    }
  }

  if (!this->_recv_buffer.empty()) {
    auto frame = this->_recv_buffer.front();
    this->_recv_buffer.pop();
    return frame;
  }

  return nullptr;
}

QUICConnectionErrorUPtr
QUICIncomingCryptoFrameBuffer::insert(const QUICFrame *frame)
{
  const QUICCryptoFrame *crypto_frame = static_cast<const QUICCryptoFrame *>(frame);

  QUICOffset offset = crypto_frame->offset();
  size_t len        = crypto_frame->data_length();

  // Ignore empty stream frame
  if (len == 0) {
    delete frame;
    return nullptr;
  }

  if (this->_recv_offset > offset) {
    // dup frame;
    delete frame;
    return nullptr;
  } else if (this->_recv_offset == offset) {
    this->_recv_offset = offset + len;
    this->_recv_buffer.push(crypto_frame);
  } else {
    auto result = this->_out_of_order_queue.insert(std::make_pair(offset, crypto_frame));
    if (!result.second) {
      // Duplicate frame doesn't need to be inserted
      delete crypto_frame;
    }
  }

  return nullptr;
}
