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

#pragma once

#include "QUICFrameGenerator.h"
#include "QUICTypes.h"
#include "QUICFrame.h"
#include <list>

class QUICConnection;

class QUICAckFrameManager : public QUICFrameGenerator
{
public:
  class QUICAckFrameCreator
  {
  public:
    struct RecvdPacket {
      bool ack_only                  = false;
      QUICPacketNumber packet_number = 0;
    };
    QUICAckFrameCreator(QUICPacketNumberSpace pn_space, QUICAckFrameManager *ack_manager);
    ~QUICAckFrameCreator();

    void push_back(QUICPacketNumber packet_number, size_t size, bool ack_only);
    size_t size() const;
    void clear();
    void sort();
    void forget(QUICPacketNumber largest_acknowledged);
    bool available() const;
    bool is_ack_frame_ready();
    void set_max_ack_delay(uint16_t delay);

    // Checks maximum_frame_size and return _ack_frame
    QUICAckFrame *generate_ack_frame(uint8_t *buf, uint16_t maximum_frame_size);

    // refresh state when frame lost
    void refresh_state();

    QUICPacketNumber largest_ack_number() const;
    ink_hrtime largest_ack_received_time() const;

  private:
    uint64_t _calculate_delay();
    QUICAckFrame *_create_ack_frame(uint8_t *buf);

    std::list<RecvdPacket> _packet_numbers;
    bool _available                         = false; // packet_number has data to sent
    bool _should_send                       = false; // ack frame should be sent immediately
    bool _has_new_data                      = false; // new data after last sent
    uint32_t _ack_eliciting_count           = 0;     // every two ack-eliciting packet should send ack immediately
    uint16_t _max_ack_delay                 = 25;
    QUICPacketNumber _largest_ack_number    = 0;
    QUICPacketNumber _expect_next           = 0;
    ink_hrtime _largest_ack_received_time   = 0;
    ink_hrtime _latest_packet_received_time = 0;

    QUICAckFrameManager *_ack_manager = nullptr;

    QUICPacketNumberSpace _pn_space = QUICPacketNumberSpace::Initial;
  };

  static constexpr int MAXIMUM_PACKET_COUNT = 256;

  QUICAckFrameManager();
  ~QUICAckFrameManager();

  void set_ack_delay_exponent(uint8_t ack_delay_exponent);
  void set_max_ack_delay(uint16_t delay);
  void set_force_to_send(bool on = true);
  bool force_to_send() const;

  /*
   * All packet numbers ATS received need to be passed to this method.
   * Returns 0 if updated successfully.
   */
  int update(QUICEncryptionLevel level, QUICPacketNumber packet_number, size_t size, bool akc_only);

  /*
   * Returns true only if should send ack.
   */
  bool will_generate_frame(QUICEncryptionLevel level, size_t current_packet_size, bool ack_eliciting, uint32_t seq_num) override;

  /*
   * Calls create directly.
   */
  QUICFrame *generate_frame(uint8_t *buf, QUICEncryptionLevel level, uint64_t connection_credit, uint16_t maximum_frame_size,
                            size_t current_packet_size, uint32_t seq_num) override;

  QUICFrameId issue_frame_id();
  uint8_t ack_delay_exponent() const;

protected:
  virtual bool _is_level_matched(QUICEncryptionLevel level) override;

private:
  virtual void _on_frame_acked(QUICFrameInformationUPtr &info) override;
  virtual void _on_frame_lost(QUICFrameInformationUPtr &info) override;

  /*
   * Returns QUICAckFrame only if ACK frame is able to be sent.
   * Caller must send the ACK frame to the peer if it was returned.
   */
  QUICAckFrame *_create_ack_frame(uint8_t *buf, QUICEncryptionLevel level);
  uint64_t _calculate_delay(QUICEncryptionLevel level);

  bool _available[4]   = {false};
  bool _should_send[4] = {false};

  // Initial, 0/1-RTT, and Handshake
  std::unique_ptr<QUICAckFrameCreator> _ack_creator[3];

  uint8_t _ack_delay_exponent = 0;
};
