/** @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 <memory>
#include <atomic>
#include <cstddef>

#include "I_IOBuffer.h"

#include "QUICTypes.h"
#include "QUICRetryIntegrityTag.h"

#define QUIC_FIELD_OFFSET_CONNECTION_ID 1
#define QUIC_FIELD_OFFSET_PACKET_NUMBER 4
#define QUIC_FIELD_OFFSET_PAYLOAD 5

class UDPConnection;

class QUICPacket
{
public:
  static constexpr int MAX_INSTANCE_SIZE = 1024;

  // Token field in Initial packet could be very long.
  static constexpr size_t MAX_PACKET_HEADER_LEN = 256;

  /**
   * Creates a QUICPacket for sending packets
   */
  QUICPacket(bool ack_eliciting, bool probing);

  virtual ~QUICPacket();

  virtual QUICPacketType type() const              = 0;
  virtual QUICConnectionId destination_cid() const = 0;
  virtual QUICPacketNumber packet_number() const   = 0;
  bool is_ack_eliciting() const;
  bool is_probing_packet() const;

  // TODO These two should be pure virtual
  virtual Ptr<IOBufferBlock>
  header_block() const
  {
    return Ptr<IOBufferBlock>();
  };
  virtual Ptr<IOBufferBlock>
  payload_block() const
  {
    return Ptr<IOBufferBlock>();
  };

  /*
   * Size of whole QUIC packet (header + payload + integrity check)
   */
  virtual uint16_t size() const;

  /*
   * Size of header
   */
  virtual uint16_t header_size() const;

  /*
   * Length of payload (payload + integrity check if exists)
   */
  virtual uint16_t payload_length() const;

  /**
   * Key phase
   */
  virtual QUICKeyPhase key_phase() const;

  // FIXME Remove this and use IOBufferBlock instead
  void store(uint8_t *buf, size_t *len) const;

  /***** STATIC MEMBERS *****/

  static uint8_t calc_packet_number_len(QUICPacketNumber num, QUICPacketNumber base);
  static bool encode_packet_number(QUICPacketNumber &dst, QUICPacketNumber src, size_t len);
  static bool decode_packet_number(QUICPacketNumber &dst, QUICPacketNumber src, size_t len, QUICPacketNumber largest_acked);

protected:
  QUICPacket();

private:
  bool _is_ack_eliciting  = false;
  bool _is_probing_packet = false;
};

class QUICPacketR : public QUICPacket
{
public:
  /**
   * Creates a QUICPacket for receiving packets
   */
  QUICPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to);

  virtual QUICPacketType type() const override = 0;

  UDPConnection *udp_con() const;
  virtual const IpEndpoint &from() const;
  virtual const IpEndpoint &to() const;

  static bool read_essential_info(Ptr<IOBufferBlock> block, QUICPacketType &type, QUICVersion &version, QUICConnectionId &dcid,
                                  QUICConnectionId &scid, QUICPacketNumber &packet_number, QUICPacketNumber base_packet_number,
                                  QUICKeyPhase &key_phase);
  static bool type(QUICPacketType &type, const uint8_t *packet, size_t packet_len);

protected:
  Ptr<IOBufferBlock> _header_block;
  Ptr<IOBufferBlock> _payload_block;

private:
  UDPConnection *_udp_con = nullptr;
  const IpEndpoint _from  = {};
  const IpEndpoint _to    = {};
};

using QUICPacketDeleterFunc = void (*)(QUICPacket *p);
using QUICPacketUPtr        = std::unique_ptr<QUICPacket, QUICPacketDeleterFunc>;

class QUICPacketDeleter
{
public:
  static void
  delete_null_packet(QUICPacket *packet)
  {
    ink_assert(packet == nullptr);
  }

  static void
  delete_dont_free(QUICPacket *packet)
  {
    packet->~QUICPacket();
  }

  static void
  delete_packet_new(QUICPacket *packet)
  {
    delete packet;
  }
};

class QUICLongHeaderPacket : public QUICPacket
{
public:
  /**
   * For sending packet
   */
  QUICLongHeaderPacket(QUICVersion version, const QUICConnectionId &dcid, const QUICConnectionId &scid, bool ack_eliciting,
                       bool probing, bool crypto);

  QUICConnectionId source_cid() const;

  QUICConnectionId destination_cid() const override;
  uint16_t payload_length() const override;
  virtual QUICVersion version() const;
  virtual bool is_crypto_packet() const;

protected:
  size_t _write_common_header(uint8_t *buf) const;

  Ptr<IOBufferBlock> _payload_block;
  size_t _payload_length = 0;

private:
  QUICVersion _version;
  QUICConnectionId _dcid;
  QUICConnectionId _scid;

  bool _is_crypto_packet;
};

class QUICLongHeaderPacketR : public QUICPacketR
{
public:
  /**
   * For receiving packet
   */
  QUICLongHeaderPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks);

  virtual ~QUICLongHeaderPacketR(){};

  QUICConnectionId destination_cid() const override;
  QUICConnectionId source_cid() const;
  virtual QUICVersion version() const;

  static bool type(QUICPacketType &type, const uint8_t *packet, size_t packet_len);
  static bool version(QUICVersion &version, const uint8_t *packet, size_t packet_len);
  static bool key_phase(QUICKeyPhase &key_phase, const uint8_t *packet, size_t packet_len);
  static bool length(size_t &length, uint8_t &length_field_len, size_t &length_field_offset, const uint8_t *packet,
                     size_t packet_len);
  static bool packet_length(size_t &packet_len, const uint8_t *buf, size_t buf_len);
  static bool packet_number_offset(size_t &pn_offset, const uint8_t *packet, size_t packet_len);

protected:
  QUICVersion _version;
  QUICConnectionId _scid;
  QUICConnectionId _dcid;
};

class QUICShortHeaderPacket : public QUICPacket
{
public:
  /**
   * For sending packet
   */
  QUICShortHeaderPacket(const QUICConnectionId &dcid, QUICPacketNumber packet_number, QUICPacketNumber base_packet_number,
                        QUICKeyPhase key_phase, bool ack_eliciting, bool probing);

  QUICPacketType type() const override;
  QUICKeyPhase key_phase() const override;
  QUICPacketNumber packet_number() const override;
  QUICConnectionId destination_cid() const override;

  uint16_t payload_length() const override;
  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;

  void attach_payload(Ptr<IOBufferBlock> payload, bool unprotected);

private:
  QUICConnectionId _dcid;
  QUICPacketNumber _packet_number;
  QUICKeyPhase _key_phase;
  int _packet_number_len;

  Ptr<IOBufferBlock> _payload_block;
  size_t _payload_length;
};

class QUICShortHeaderPacketR : public QUICPacketR
{
public:
  /**
   * For receiving packet
   */
  QUICShortHeaderPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks,
                         QUICPacketNumber base_packet_number);

  void attach_payload(Ptr<IOBufferBlock> payload, bool unprotected);

  QUICPacketType type() const override;
  QUICKeyPhase key_phase() const override;
  QUICPacketNumber packet_number() const override;
  QUICConnectionId destination_cid() const override;

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;

  static bool packet_number_offset(size_t &pn_offset, const uint8_t *packet, size_t packet_len, int dcil);

private:
  QUICKeyPhase _key_phase;
  QUICPacketNumber _packet_number;
  int _packet_number_len;
  QUICConnectionId _dcid;
};

class QUICStatelessResetPacket : public QUICPacket
{
public:
  /**
   * For sending packet
   */
  QUICStatelessResetPacket(QUICStatelessResetToken token, size_t maximum_size);

  QUICPacketType type() const override;
  QUICPacketNumber packet_number() const override;
  QUICConnectionId destination_cid() const override;

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;

  QUICStatelessResetToken token() const;

private:
  QUICStatelessResetToken _token;
  size_t _maximum_size;
};

class QUICStatelessResetPacketR : public QUICPacketR
{
public:
  /**
   * For receiving packet
   */
  QUICStatelessResetPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks);

  QUICPacketType type() const override;
  QUICPacketNumber packet_number() const override;
  QUICConnectionId destination_cid() const override;
};

class QUICVersionNegotiationPacket : public QUICLongHeaderPacket
{
public:
  /**
   * For sending packet
   */
  QUICVersionNegotiationPacket(QUICConnectionId dcid, QUICConnectionId scid, const QUICVersion versions[], int nversions);

  QUICPacketType type() const override;
  QUICVersion version() const override;
  QUICPacketNumber packet_number() const override;
  uint16_t payload_length() const override;

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;

  const QUICVersion *versions() const;
  int nversions() const;

private:
  const QUICVersion *_versions;
  int _nversions;
};

class QUICVersionNegotiationPacketR : public QUICLongHeaderPacketR
{
public:
  /**
   * For receiving packet
   */
  QUICVersionNegotiationPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks);

  QUICPacketType type() const override;
  QUICPacketNumber packet_number() const override;
  QUICConnectionId destination_cid() const override;

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;

  const QUICVersion supported_version(uint8_t index) const;
  int nversions() const;

private:
  QUICConnectionId _dcid;
  uint8_t *_versions;
  int _nversions;
};

class QUICInitialPacket : public QUICLongHeaderPacket
{
public:
  /**
   * For sending packet
   */
  QUICInitialPacket(QUICVersion version, const QUICConnectionId &dcid, const QUICConnectionId &scid, size_t token_len,
                    ats_unique_buf token, size_t length, QUICPacketNumber packet_number, bool ack_eliciting, bool probing,
                    bool crypto);

  QUICPacketType type() const override;
  QUICPacketNumber packet_number() const override;
  QUICKeyPhase key_phase() const override;

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;
  void attach_payload(Ptr<IOBufferBlock> payload, bool unprotected);

private:
  size_t _token_len     = 0;
  ats_unique_buf _token = ats_unique_buf(nullptr);
  QUICPacketNumber _packet_number;
};

class QUICInitialPacketR : public QUICLongHeaderPacketR
{
public:
  /**
   * For receiving packet
   */
  QUICInitialPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks,
                     QUICPacketNumber base_packet_number);
  ~QUICInitialPacketR();

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;
  void attach_payload(Ptr<IOBufferBlock> payload, bool unprotected);

  QUICPacketType type() const override;
  QUICPacketNumber packet_number() const override;
  QUICKeyPhase key_phase() const override;

  const QUICAddressValidationToken &token() const;

  static bool token_length(size_t &token_length, uint8_t &field_len, size_t &token_length_filed_offset, const uint8_t *packet,
                           size_t packet_len);

protected:
  Ptr<IOBufferBlock> _payload_block;

private:
  QUICPacketNumber _packet_number;
  QUICAddressValidationToken *_token = nullptr;

  bool _parse();
};

class QUICZeroRttPacket : public QUICLongHeaderPacket
{
public:
  /**
   * For sending packet
   */
  QUICZeroRttPacket(QUICVersion version, const QUICConnectionId &dcid, const QUICConnectionId &scid, size_t length,
                    QUICPacketNumber packet_number, bool ack_eliciting, bool probing);

  QUICPacketType type() const override;
  QUICPacketNumber packet_number() const override;
  QUICKeyPhase key_phase() const override;

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;
  void attach_payload(Ptr<IOBufferBlock> payload, bool unprotected);

private:
  QUICPacketNumber _packet_number;
};

class QUICZeroRttPacketR : public QUICLongHeaderPacketR
{
public:
  /**
   * For receiving packet
   */
  QUICZeroRttPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks,
                     QUICPacketNumber base_packet_number);

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;
  void attach_payload(Ptr<IOBufferBlock> payload, bool unprotected);

  QUICPacketType type() const override;
  QUICPacketNumber packet_number() const override;
  QUICKeyPhase key_phase() const override;

private:
  QUICPacketNumber _packet_number;
};

class QUICHandshakePacket : public QUICLongHeaderPacket
{
public:
  /**
   * For sending packet
   */
  QUICHandshakePacket(QUICVersion version, const QUICConnectionId &dcid, const QUICConnectionId &scid, size_t length,
                      QUICPacketNumber packet_number, bool ack_eliciting, bool probing, bool crypto);

  QUICPacketType type() const override;
  QUICKeyPhase key_phase() const override;
  QUICPacketNumber packet_number() const override;

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;
  void attach_payload(Ptr<IOBufferBlock> payload, bool unprotected);

private:
  QUICPacketNumber _packet_number;
};

class QUICHandshakePacketR : public QUICLongHeaderPacketR
{
public:
  /**
   * For receiving packet
   */
  QUICHandshakePacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks,
                       QUICPacketNumber base_packet_number);

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;
  void attach_payload(Ptr<IOBufferBlock> payload, bool unprotected);

  QUICPacketType type() const override;
  QUICKeyPhase key_phase() const override;
  QUICPacketNumber packet_number() const override;

private:
  QUICPacketNumber _packet_number;
};

class QUICRetryPacket : public QUICLongHeaderPacket
{
public:
  /**
   * For sending packet
   */
  QUICRetryPacket(QUICVersion version, const QUICConnectionId &dcid, const QUICConnectionId &scid, QUICRetryToken &token);

  QUICPacketType type() const override;
  QUICPacketNumber packet_number() const override;
  uint16_t payload_length() const override;

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;

  const QUICRetryToken &token() const;

private:
  QUICRetryToken _token;

  bool _compute_retry_integrity_tag(uint8_t *out, QUICConnectionId odcid, Ptr<IOBufferBlock> header,
                                    Ptr<IOBufferBlock> payload) const;
};

class QUICRetryPacketR : public QUICLongHeaderPacketR
{
public:
  /**
   * For receiving packet
   */
  QUICRetryPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks);
  ~QUICRetryPacketR();

  Ptr<IOBufferBlock> header_block() const override;
  Ptr<IOBufferBlock> payload_block() const override;

  QUICPacketType type() const override;
  QUICPacketNumber packet_number() const override;

  const QUICAddressValidationToken &token() const;
  bool has_valid_tag(const QUICConnectionId &odcid) const;

private:
  QUICAddressValidationToken *_token = nullptr;
  uint8_t _integrity_tag[QUICRetryIntegrityTag::LEN];
  Ptr<IOBufferBlock> _payload_block_without_tag;
};
