/** @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 "QUICFrameDispatcher.h"
#include "QUICDebugNames.h"

static constexpr char tag[] = "quic_net";

#define QUICDebug(fmt, ...) Debug(tag, "[%s] " fmt, this->_info->cids().data(), ##__VA_ARGS__)

//
// Frame Dispatcher
//
QUICFrameDispatcher::QUICFrameDispatcher(QUICConnectionInfoProvider *info) : _info(info) {}

void
QUICFrameDispatcher::add_handler(QUICFrameHandler *handler)
{
  for (QUICFrameType t : handler->interests()) {
    this->_handlers[static_cast<uint8_t>(t)].push_back(handler);
  }
}

QUICConnectionErrorUPtr
QUICFrameDispatcher::receive_frames(QUICEncryptionLevel level, const uint8_t *payload, uint16_t size, bool &ack_only,
                                    bool &is_flow_controlled, bool *has_non_probing_frame, const QUICPacket *packet)
{
  uint16_t cursor               = 0;
  ack_only                      = true;
  is_flow_controlled            = false;
  QUICConnectionErrorUPtr error = nullptr;

  while (cursor < size) {
    const QUICFrame &frame = this->_frame_factory.fast_create(payload + cursor, size - cursor, packet);
    if (frame.type() == QUICFrameType::UNKNOWN) {
      QUICDebug("Failed to create a frame (%u bytes skipped)", size - cursor);
      break;
    }
    if (has_non_probing_frame) {
      *has_non_probing_frame |= !frame.is_probing_frame();
    }
    cursor += frame.size();

    QUICFrameType type = frame.type();

    if (type == QUICFrameType::STREAM) {
      is_flow_controlled = true;
    }

    if (is_debug_tag_set(tag) && type != QUICFrameType::PADDING) {
      char msg[1024];
      frame.debug_msg(msg, sizeof(msg));
      QUICDebug("[RX] | %s", msg);
    }

    if (type != QUICFrameType::PADDING && type != QUICFrameType::ACK) {
      ack_only = false;
    }

    std::vector<QUICFrameHandler *> handlers = this->_handlers[static_cast<uint8_t>(type)];
    for (auto h : handlers) {
      error = h->handle_frame(level, frame);
      // TODO: is there any case to continue this loop even if error?
      if (error != nullptr) {
        return error;
      }
    }
  }

  return error;
}
